前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MyBatis快速入门

MyBatis快速入门

作者头像
不愿意做鱼的小鲸鱼
发布2022-09-24 09:29:36
3800
发布2022-09-24 09:29:36
举报
文章被收录于专栏:web全栈web全栈

1、什么是框架?

代码语言:javascript
复制
它是我们软件开发中的一套解决方案,不同的框架解决的是不同的问题。
使用框架的好处:
    框架封装了很多的细节,使开发者可以使用极简的方式实现功能。大大提高开发效率。

2、三层架构

代码语言:javascript
复制
表现层:
    是用于展示数据的
业务层:
    是处理业务需求
持久层:
    是和数据库交互的

3、持久层技术解决方案

代码语言:javascript
复制
JDBC技术:
    Connection
    PreparedStatement
    ResultSet
Spring的JdbcTemplate:
    Spring中对jdbc的简单封装
Apache的DBUtils:
    它和Spring的JdbcTemplate很像,也是对Jdbc的简单封装

以上这些都不是框架
    JDBC是规范
    Spring的JdbcTemplate和Apache的DBUtils都只是工具类

4.MyBatis

mybatis的概述

代码语言:javascript
复制
mybatis是一个持久层框架,用java编写的。
它封装了jdbc操作的很多细节,使开发者只需要关注sql语句本身,而无需关注注册驱动,创建连接等繁杂过程
它使用了ORM思想实现了结果集的封装。

mybatis的入门

mybatis的环境搭建
  • 第一步:创建maven工程并导入坐标
代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.qkongtao</groupId>
    <artifactId>MyBatis1</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.35</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
</project>
  • 创建实体类和dao的接口
代码语言:javascript
复制
package dao;
import domain.User;
import java.util.List;
/**
 *
 * 用户的持久层接口
 */
public interface IUserDao {
    /**
     * 查询所有操作
     * @return
     */
    List<User> findAll();
}
  • 创建Mybatis的主配置文件 SqlMapConifg.xml
代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- mybatis的主配置文件 -->
<configuration>
    <!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置数据源(连接池) -->
            <dataSource type="POOLED">
                <!-- 配置连接数据库的4个基本信息 -->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/eesy"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
    <mappers>
        <mapper resource="dao/IUserDao.xml"/>
    </mappers>
     <!--起别名,可以不用谢写全限定类名-->
    <typeAliases>
        <typeAlias type="domain.User" alias="user"></typeAlias>
    </typeAliases>
</configuration>
  • 创建映射配置文件 IUserDao.xml
代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.IUserDao">
    <!--配置查询所有-->
    <select id="findAll" resultType="domain.User">
        select * from user
    </select>
</mapper>
环境搭建的注意事项:
  • 创建IUserDao.xml 和 IUserDao.java时名称是为了和我们之前的知识保持一致。在Mybatis中它把持久层的操作接口名称和映射文件也叫做:Mapper,所以:IUserDao 和 IUserMapper是一样的
  • 在idea中创建目录的时候,它和包是不一样的包在创建时:com.itheima.dao它是三级结构目录在创建时:com.itheima.dao是一级目录
  • mybatis的映射配置文件位置必须和dao接口的包结构相同
  • 映射配置文件的mapper标签namespace属性的取值必须是dao接口的全限定类名
  • 映射配置文件的操作配置(select),id属性的取值必须是dao接口的方法名
mybatis的入门案例
  1. 读取配置文件
代码语言:javascript
复制
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
  1. 创建SqlSessionFactory工厂
代码语言:javascript
复制
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
  1. 创建SqlSession
代码语言:javascript
复制
 SqlSession session = factory.openSession();
  1. 创建Dao接口的代理对象
代码语言:javascript
复制
 IUserDao userDao = session.getMapper(IUserDao.class);
  1. 执行dao中的方法
代码语言:javascript
复制
List<User> users = userDao.findAll();
        for(User user : users){
            System.out.println(user);
        }
  1. 释放资源
代码语言:javascript
复制
session.close();
        in.close();

注意事项: 不要忘记在映射配置中告知mybatis要封装到哪个实体类中 配置的方式:指定实体类的全限定类名

mybatis基于注解的入门案例:

把IUserDao.xml移除,在dao接口的方法上使用@Select注解,并且指定SQL语句,同时需要在SqlMapConfig.xml中的mapper配置时,使用class属性指定dao接口的全限定类名。

代码语言:javascript
复制
package dao;

import domain.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
 *
 * 用户的持久层接口
 */
public interface IUserDao {

    /**
     * 查询所有操作
     * @return
     */
    @Select("select * from user")
    List<User> findAll();
}

明确: 我们在实际开发中,都是越简便越好,所以都是采用不写dao实现类的方式。不管使用XML还是注解配置。但是Mybatis它是支持写dao实现类的。

MyBatis连接池:

我们在实际开发中都会使用连接池。 因为它可以减少我们获取连接所消耗的时间。

mybatis中的连接池 mybatis连接池提供了3种方式的配置: 配置的位置: 主配置文件SqlMapConfig.xml中的dataSource标签,type属性就是表示采用何种连接池方式。

代码语言:javascript
复制
 <!-- 配置数据源(连接池) -->
 <dataSource type="POOLED">
     <!-- 配置连接数据库的4个基本信息 -->
     <property name="driver" value="com.mysql.jdbc.Driver"/>
     <property name="url" value="jdbc:mysql://localhost:3306/eesy"/>
     <property name="username" value="root"/>
     <property name="password" value="root"/>
 </dataSource>

type属性的取值: 1. POOLED 采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现 2. UNPOOLED 采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的思想。 3. JNDI 采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样。 注意:如果不是web或者maven的war工程,是不能使用的。我们使用的是tomcat服务器,采用连接池就是dbcp连接池。

MyBatis动态 SQL

  1. 动态 SQL 之标签我们根据实体类的不同取值,使用不同的 SQL 语句来进行查询。比如在 id 如果不为空时可以根据 id 查询,如果 username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。
代码语言:javascript
复制
<select id="findUserByCondition" resultMap="userMap" resultType="domain.User">
        select * from user where 1 =1
        <if test="name != null">
           and name = #{name}
        </if>
        <if test="sex != null">
            and sex = #{sex}
        </if>
</select>
  1. 动态 SQL 之标签 为了简化上面 where 1=1 的条件拼装,我们可以采用标签来简化开发。
代码语言:javascript
复制
<select id="findUserByCondition" resultMap="userMap" resultType="domain.User">
        select * from user
        <where>
            <if test="name != null">
                and name = #{name}
            </if>
            <if test="sex != null">
                and sex = #{sex}
            </if>
        </where>
</select>
  1. 动态标签之标签 传入多个 id 查询用户信息,用下边两个 sql 实现:
代码语言:javascript
复制
SELECT * FROM USERS WHERE username LIKE '%张%' AND (id =10 OR id =89 OR id=16)
SELECT * FROM USERS WHERE username LIKE '%张%' AND id IN (10,89,16)

这样我们在进行范围查询时,就要将一个集合中的值,作为参数动态添加进来。 * 在 QueryVo 中加入一个 List 集合用于封装参数

代码语言:javascript
复制
/**
    package domain;/*
 *Created by tao on 2020-03-26.
 */

import java.util.List;

public class QueryVo {
    private  User user;
    private List<Integer> ids;

    public List<Integer> getIds() {
        return ids;
    }

    public void setIds(List<Integer> ids) {
        this.ids = ids;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}
  • 持久层 Dao 接口
代码语言:javascript
复制
/**
     根据QueryVo中的提供的Id集合查询用户信息
     *
     * @param vo
     * @return
     */
    List<User> findUserInIds(QueryVo vo);
  • 持久层 Dao 映射配置
代码语言:javascript
复制
<!--根据QueryVo中的Id集合查询用户列表-->
<select id="findUserInIds" resultMap="userMap" parameterType="domain.QueryVo">
   select * from user
   <where>
      <if test="ids != null and ids.size()>0">
          <foreach collection="ids" open="and id in (" close=")" item="uid" separator=",">
              #{uid}
          </foreach>
      </if>
   </where>
</select>

foreach SQL语句 * 标签用于遍历集合,它的属性: * collection:代表要遍历的集合元素,注意编写时不要写#{} * open:代表语句的开始部分 * close:代表结束部分 * item:代表遍历集合的每个元素,生成的变量名 * sperator:代表分隔符

MyBatis多表查询

IUserDao配置如下

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="dao.IUserDao">
    <!-- 配置 查询结果的列名和实体类的属性名的对应关系 -->

    <!--一对一:定义 AccountUser 表的 accountMap-->
    <resultMap id="accountMap" type="domain.AccountUser">
        <id column="aid" property="id"/>
        <result column="uid" property="uid"/>
        <result column="money" property="money"/>
        <!-- 它是用于指定从表方的引用实体属性的 -->
        <association property="user" javaType="domain.User">
            <id column="id" property="id"/>
            <result column="name" property="name"/>
            <result column="sex" property="sex"/>
            <result column="birthday" property="birthday"/>
            <result column="age" property="age"/>
        </association>
    </resultMap>

    <!--一对多:定义 user 表的 userMap-->
    <resultMap id="userMap" type="domain.User">
        <!-- 主键字段的对应 -->
        <id property="id" column="id"></id>
        <!--非主键字段的对应-->
        <result property="name" column="name"></result>
        <result property="birthday" column="birthday"></result>
        <result property="sex" column="sex"></result>
        <result property="age" column="age"></result>
        <!-- collection 是用于建立一对多中集合属性的对应关系ofType 用于指定集合元素的数据类型-->
        <collection property="accounts" ofType="domain.Account">
            <id column="aid" property="id"/>
            <result column="uid" property="uid"/>
            <result column="money" property="money"/>
        </collection>
    </resultMap>

    <!--多对多:定义 role 表的 ResultMap-->
    <resultMap id="roleMap" type="domain.Role">
        <id property="roleId" column="rid"></id>
        <result property="roleName" column="role_name"></result>
        <result property="roleDesc" column="role_desc"></result>
        <collection property="users" ofType="domain.User">
            <id column="id" property="id"></id>
            <result column="username" property="name"></result>
            <result column="age" property="age"></result>
            <result column="sex" property="sex"></result>
            <result column="birthday" property="birthday"></result>
        </collection>
    </resultMap>


    <!-- 一对一查询所有 -->
    <select id="findAll" resultMap="accountMap">
        select u.*,a.id as aid,a.uid,a.money from account a,user u where a.uid =u.id;
    </select>

    <!--一对多查询所有-->
    <select id="findAllDuo" resultMap="userMap">
      select u.*,a.id as aid ,a.uid,a.money from user u left outer join account
       a on u.id =a.uid
    </select>

    <!--一对多查询-->
    <select id="findAllDDD" resultMap="roleMap">
        select u.*,r.id as rid,r.role_name,r.role_desc from role r left outer join user_role ur on r.id = ur.rid
         left outer join user u on u.id = ur.uid;
    </select>

</mapper>
  • collection: 部分定义了用户关联的账户信息。表示关联查询结果集
  • property="accList": 关联查询的结果集存储在 User 对象的上哪个属性。
  • ofType="account": 指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名。

开启 Mybatis 的延迟加载策略

  • 什么是延迟加载 在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)
  • 什么是立即加载 不管用不用,只要一调用方法,马上发起查询。
  • 在对应的四种表关系中:一对多,多对一,一对一,多对多 一对多,多对多:通常情况下我们都是采用延迟加载。 多对一,一对一:通常情况下我们都是采用立即加载。

我们需要在 Mybatis 的配置文件 SqlMapConfig.xml 文件中添加延迟加载的配置。

代码语言:javascript
复制
<!-- 开启延迟加载的支持 -->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>

Mybatis中的注解开发

要用注解都用注解,要用xml都用xml,不能同时存在,不然会报错

Mybatis 缓存

像大多数的持久化框架一样,Mybatis 也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提 高性能。 Mybatis 中缓存分为一级缓存,二级缓存。 1. 什么是缓存 存在于内存中的临时数据。 2. 为什么使用缓存 减少和数据库的交互次数,提高执行效率。 什么样的数据能使用缓存,什么样的数据不能使用 3. 适用于缓存: * 经常查询并且不经常改变的。 * 数据的正确与否对最终结果影响不大的。 4. 不适用于缓存: * 经常改变的数据 * 数据的正确与否对最终结果影响很大的。 * 例如:商品的库存,银行的汇率,股市的牌价。

一级缓存

在不修改数据库的情况下,查询了两次,但最后只执行了一次数据库操作,这就是 Mybatis 提供给我们的一级缓存在起作用了。 **一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。 ** * 手动清空一级缓存 sqlSession.clearCache();//此方法也可以清空缓存

二级缓存:

它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。 二级缓存的使用步骤:

第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)

代码语言:javascript
复制
<!--配置二级缓存-->
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>

第二步:让当前的映射文件支持二级缓存(在IUserDao.xml中配置)

代码语言:javascript
复制
<!--开启二级缓存-->
    <cache/>

第三步:让当前的操作支持二级缓存(在select标签中配置)

代码语言:javascript
复制
 <!-- 一对一查询所有 -->
    <select id="findAll" resultMap="accountMap" useCache="true">
        select u.*,a.id as aid,a.uid,a.money from account a,user u where a.uid =u.id;
    </select>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、什么是框架?
  • 2、三层架构
  • 3、持久层技术解决方案
  • 4.MyBatis
    • mybatis的概述
      • mybatis的入门
        • mybatis的环境搭建
        • 环境搭建的注意事项:
        • mybatis的入门案例
        • mybatis基于注解的入门案例:
      • MyBatis连接池:
        • MyBatis动态 SQL
          • MyBatis多表查询
            • 开启 Mybatis 的延迟加载策略
              • Mybatis中的注解开发
                • Mybatis 缓存
                  • 一级缓存
                  • 二级缓存:
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档