栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mybatis框架复习[详细记录]

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mybatis框架复习[详细记录]

目录

一、搭建Mybatis

二、JUnit测试添加功能

三、加入log4j日志

四、Mybatis的简单增删改查

五、封装SqlSessionUtils工具类并测试功能

六、Mybatis获取参数值的两种方式

七、MyBatis的各种查询功能

八、Mybatis中特殊SQL的执行

九、自定义映射resultMap

十、动态SQL

十一、Mybatis的缓存

十二、Mybatis的逆向工程


一、搭建Mybatis

1、开发环境
  • IDE:IntelliJ IDEA 2021.2.3
  • 构建工具:Maven 3.6.3
  • MySQL版本:MySQL 5.7
  • MyBatis版本:3.5.7

2、创建数据库和表
  • 创建名为mybatis 的数据库
  • 在数据库中新建数据表 t_user 字段如下图所示

3、创建Maven工程,在pom文件中引入依赖
 
        
        
            org.mybatis
            mybatis
            3.5.7
        
        
        
            junit
            junit
            4.12
            test
        
        
        
            mysql
            mysql-connector-java
            5.1.3
        
    

3、创建Mybatis的核心配置文件
  • 习惯上命名为 mybatis-config.xml
  • 存放的位置是 src/main/resources 目录下
  • 核心配置文件主要用于配置连接数据库的环境以及MyBatis的全局配置信息




    
    
        
            
            
            
                
                
                
                
                
                
                
                
            
        
    
    
    
        
    

4、创建实体类
  • 保证 数据表字段名 和 实体类属性名 一致
  • 设置setter、getter方法,有参构造、无参构造和 toString 方法

public class User {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private String sex;
    private String email;

    public User(Integer id, String username, String password, Integer age, String sex, String email) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.age = age;
        this.sex = sex;
        this.email = email;
    }

    public User() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + ''' +
                ", password='" + password + ''' +
                ", age=" + age +
                ", sex='" + sex + ''' +
                ", email='" + email + ''' +
                '}';
    }
}

5、创建mapper接口
  • MyBatis中的mapper接口相当于以前的 dao
  • 区别在于,mapper仅仅是接口,不需要提供实现类

public interface UserMapper {
    
    int insertUser();
}

6、创建MyBatis的映射文件

ORM(Object Relationship Mapping)对象关系映射:

  • 对象:Java的实体类对象
  • 关系:关系型数据库
  • 映射:二者之间的对应关系 

映射文件的命名规则:

  • 表所对应的实体类的类名+Mapper.xml
  • 一个映射文件对应一个实体类,对应一张表的操作
  • MyBatis映射文件用于编写SQL,访问以及操作表中的数据
  • MyBatis映射文件存放的位置是 src/main/resources/mappers 目录下

MyBatis中可以面向接口操作数据,要保证两个一致:

  • mapper接口的 全类名 和映射文件的 命名空间 namespace 保持一致
  • mapper接口中方法的 方法名 和映射文件中编写SQL的标签的 id属性 保持一致




    
    
        insert into t_user values(null,'张三','123456',18,'男','123456@qq.com')
    

二、JUnit测试添加功能

在test文件夹下新建 MybatisTest测试类

  •  SqlSession:代表Java程序和数据库之间的会话
  • SqlSessionFactory:是“生产”SqlSession的“工厂”
  • 工厂模式:如果创建某一个对象,使用的过程基本固定,那么我们就可以把创建这个对象的 相关代码封装到一个“工厂类”中,以后都使用这个工厂类来“生产”我们需要的对象。
public class MybatisTest {

    

    @Test
    public void testMyBatis() throws IOException{
        //加载核心配置文件
        InputStream is=Resources.getResourceAsStream("mybatis-config.xml");
        //获取sqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //通过核心配置文件所对应的字节输入流创建工厂类SqlSessionFactory,生产SqlSession对象
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
        //获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        //获取mapper接口对象 通过代理模式创建UserMapper接口的代理实现类对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //测试功能
        int result = userMapper.insertUser();
        //提交事务
        sqlSession.commit();
        System.out.println("result: "+result);
    }

}

测试结果,返回受影响的行数

三、加入log4j日志

1、在pom.xml文件中加入依赖


    log4j
    log4j
    1.2.17

2、加入配置文件 log4j.xml

log4j的配置文件名为log4j.xml,存放位置是 src/main/resources 目录下




    
        
        
            
        
    
    
        
    
    
        
    
    
        
        
    

输出的日志

日志级别:

  • FATAL(致命)>ERROR(错误)>WARN(警告)>INFO(信息)>DEBUG(调试)
  • 从左到右打印的内容越来越详细 

四、Mybatis的简单增删改查

先在mapper接口中定义方法,再到相应的映射文件中写sql语句

public interface UserMapper {

    // 添加用户信息
    int insertUser();

    // 删除用户信息
    int deleteUser();

    // 修改用户信息
    int updateUser();

    // 查询查询一个实体类对象
    User getUserById();

    // 查询集合
    List getUserList();

}

1、添加 insert
    
        insert into t_user values(null,'小王','123564',18,'女','234567@qq.com')
    

2、删除 delete
    
    
        delete from t_user where id = 3
    

3、修改 update
    
    
        update t_user set username='xiaowang',password='123333' where id = 2
    

4、查询 select

注意:

1、select标签 必须设置属性 resultType 或 resultMap,用于设置实体类和数据库表的映射关系

  • resultType:自动映射,用于属性名和表中字段名一致的情况
  • resultMap:自定义映射,用于一对多或多对一或字段名和属性名不一致的情况

2、当查询的数据为多条时,不能使用实体类作为返回值,只能使用集合,否则会抛出异常 TooManyResultsException;但是若查询的数据只有一条,可以使用实体类或集合作为返回值

查询一个实体类对象

    
    
        select * from t_user
    

测试修改和删除功能:

t_user 原始数据

1、编写 testUpdate 测试类

    @Test
    public void testUpdate() throws IOException {
        InputStream is=Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        int result = userMapper.updateUser();
        System.out.println("result: "+result);
    }

执行结果:修改成功

 2、编写 testDelete 测试类

 @Test
    public void testDelete() throws IOException {
        InputStream is=Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        int result = userMapper.deleteUser();
        System.out.println("result: "+result);
    }

执行结果:成功删除id为3的数据

 测试查询功能:

1、编写 testGetUserById 测试类

@Test
    public void testGetUserById() throws IOException {
        InputStream is=Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user=userMapper.getUserById();
        System.out.println(user);
    }

执行结果:查询出id=2的数据

2、 编写 testGetUserList测试类

@Test
    public void testGetUserList() throws IOException {
        InputStream is=Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List list=userMapper.getUserList();
        list.forEach(user -> System.out.println(user));
    }

执行结果:返回所有数据集合

五、封装SqlSessionUtils工具类并测试功能

1、封装SqlSessionUtils工具类

public class SqlSessionUtils {
    public static SqlSession getSqlSession() {
        SqlSession sqlSession = null;
        try {
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            sqlSessionFactory.openSession(true);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sqlSession;
    }
}

2、测试

项目结构:

ParameterMapper 接口:

public interface ParameterMapper {
    //查询所有员工信息
    List getAllUser();
}

ParameterMapper.xml 映射文件:





    
        select * from t_user where username = #{username}
    

testGetUserByUsername测试类

@Test
    public void testGetUserByUsername(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        ParameterMapper parameterMapper =sqlSession.getMapper(ParameterMapper.class);
        User user=parameterMapper.getUserByUsername("xiaowang");
        System.out.println(user);
    }

查看日志,#{}本质就是占位符赋值,传输的参数名不重要,和位置有关

将映射文件中的 #{} 改成 ${} ,再次执行测试类查看结果

 查看日志,发现参数缺少引号,${} 本质是字符串拼接,需要自己加上引号

 

 2、参数为多个字面量类型

在ParameterMapper接口中加入 

    //验证登录
    User ckeckLogin(String username,String password);

 在ParameterMapper.xml中加入 (利用 #{} 获取参数)

    
        select * from t_user where username = #{username}  and password =#{password}
    

testCheckLoginByMap测试类

  @Test
    public void testCheckLoginByMap(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        ParameterMapper parameterMapper =sqlSession.getMapper(ParameterMapper.class);
        Map map=new HashMap<>();
        map.put("username","张三");
        map.put("password","123456");
        User user=parameterMapper.checkLoginByMap(map);
        System.out.println(user);
    }

执行结果:成功返回对应用户信息

4、参数为实体类类型
  • mapper接口中的方法参数为实体类对象时可以使用${}和#{},
  • 通过访问实体类对象中的属性名获取属性值,注意${}需要手动加单引号

在ParameterMapper接口中加入 

    //添加用户信息
    int insertUser(User user);

在ParameterMapper.xml中加入 (利用 #{} 获取参数,通过属性名获取属性值)

    
        insert into t_user values (null,#{username},#{password},#{age},#{sex},#{email})
    

testInsertUser测试类

 @Test
    public void testInsertUser(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        ParameterMapper parameterMapper =sqlSession.getMapper(ParameterMapper.class);
        int result=parameterMapper.insertUser(new User(null,"小蓝","123455",22,"男","654872@123.com"));
        System.out.println(result);
    }

执行结果:成功添加用户信息

5、使用@Param命名参数
  • 通过@Param注解标识mapper接口中的方法参数
  • Mybatis会将这些参数放在map集合中,以@Param注解的value属性值为键,以参数为值
  • 或者以 param1,param2...为键,以参数为值
  • 只需要通过${}和#{}访问map集合的键就可以获取相对应的值, 注意${}需要手动加单引号

在ParameterMapper接口中加入 

//验证登录(使用@Param)
    User checkLoginByParam(@Param("username")String username,@Param("password") String password);

在ParameterMapper.xml中加入 (利用 #{} 获取参数)

    
        select * from t_user where id = #{Id}
    

SelectMapperTest测试类中的testGetUserById

public class SelectMapperTest {
    @Test
    public void testGetUserById(){
        SqlSession sqlSession= SqlSessionUtils.getSqlSession();
        SelectMapper selectMapper=sqlSession.getMapper(SelectMapper.class);
        User user=selectMapper.getUserById(2);
        System.out.println(user);
    }
}

执行结果:成功返回id=2的用户信息 

2、查询一个list集合
  • 查询出的数据有多条,可以通过list集合接收

SelectMapper接口加入

    //查询所有用户信息
    List getUserList();

SelectMapper.xml 加入

    
        select count(*) from t_user
    

testGetCount测试类

 @Test
    public void testGetCount(){
        SqlSession sqlSession= SqlSessionUtils.getSqlSession();
        SelectMapper selectMapper=sqlSession.getMapper(SelectMapper.class);
        System.out.println(selectMapper.getCount());
    }

执行结果:返回t_user表的记录数

4、查询一条数据为map集合

SelectMapper接口加入

    //根据id用户信息为一个map集合
    Map getUserByIdToMap(@Param("Id") Integer id)

SelectMapper.xml 加入

    
        select * from t_user
    

testGetAllUserToMap测试类

    @Test
    public void testGetAllUserToMap1(){
        SqlSession sqlSession= SqlSessionUtils.getSqlSession();
        SelectMapper selectMapper=sqlSession.getMapper(SelectMapper.class);
        System.out.println(selectMapper.getAllUserToMap());
    }

执行结果:

方法二:
  • 要以一个map的方式返回数据,需要通过@MapKey注解设置map集合的键
  • 值是每条数据所对应的map集合
    //查询所有用户信息为map集合
    @MapKey("id")
    Map getAllUserToMap();

执行结果:id为键,每条数据所对应的map集合为值 的map集合

八、Mybatis中特殊SQL的执行

新建SQLMapper接口,SQLMapper.xml 及 SQLMapperTest测试类

1、模糊查询

SQLMapper接口

public interface SQLMapper {
    //根据用户名模糊查询用户信息
    List getUserByLike(@Param("username") String username);
}

SQLMapperTest测试类中的testGetUserByLike

public class SQLMapperTest {
    @Test
    public void testGetUserByLike(){
        SqlSession sqlSession= SqlSessionUtils.getSqlSession();
        SQLMapper sqlMapper=sqlSession.getMapper(SQLMapper.class);
        List list=sqlMapper.getUserByLike("小");
        System.out.println(list);
    }
}

方案一: ${} 接收参数
    
        select * from t_user where username like concat('%',#{username},'%')
    

方案三:用双引号包含%拼接
    
        select * from ${tableName}
    

testGetUserByTableName测试类

    @Test
    public void testGetUserByTableName(){
        SqlSession sqlSession= SqlSessionUtils.getSqlSession();
        SQLMapper sqlMapper=sqlSession.getMapper(SQLMapper.class);
        List list=sqlMapper.getUserByTableName("t_user");
        list.forEach(user -> System.out.println(user));
    }

执行结果: 成功查询出表t_user的用户数据

4、添加功能获取自增的主键
  • useGeneratedKeys:设置使用自增的主键
  • keyProperty:将自增的主键的值赋值给传输到映射文件中参数的某个属性

SQLMapper接口

    //添加用户信息
    void insertUser(User user);

SQLMapper.xml

因为增删改有统一的返回值是受影响的行数,

因此只能将获取的自增的主键放在传输的参 数user对象的id中

    
        insert into t_user values(null,#{username},#{password},#{age},#{sex},#{email})
    

testInsertUser测试类 这里传入的id为null,自动递增

    @Test
    public void testInsertUser(){
        SqlSession sqlSession= SqlSessionUtils.getSqlSession();
        SQLMapper sqlMapper=sqlSession.getMapper(SQLMapper.class);
        User user=new User(null,"王五","135659",21,"男","12356@123.com");
        sqlMapper.insertUser(user);
        System.out.println(user);
    }

执行结果:执行完添加操作之后,user对象的id属性的值为自增的主键

九、自定义映射resultMap

新建两个新的数据表 t_emp t_dept

 加入数据

创建Emp、Dept实体类、mapper接口、映射文件

实体类Emp

public class Emp {
    private Integer eid;

    private String empName;

    private Integer age;

    private String sex;

    private String email;

    public Emp(Integer eid, String empName, Integer age, String sex, String email) {
        this.eid = eid;
        this.empName = empName;
        this.age = age;
        this.sex = sex;
        this.email = email;
    }

    public Emp() {
    }

    public Integer getEid() {
        return eid;
    }

    public void setEid(Integer eid) {
        this.eid = eid;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "eid=" + eid +
                ", empName='" + empName + ''' +
                ", age=" + age +
                ", sex='" + sex + ''' +
                ", email='" + email + ''' +
                '}';
    }
}

EmpMapper接口

public interface EmpMapper {
    //查询所有员工信息
    List getAllEmp();
}

EmpMapper.xml





    
        select eid,emp_name empName,age,sex,email from t_emp
    

方案二:设置全局配置

在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase,

在查询表中数据时,自动将下划线类型的字段名转换为驼峰类型 emp_name -> empName

    
        
        
    

方式三:通过resultMap设置自定义映射关系

resultMap属性:

  • id:表示自定义映射的唯一标识
  • type:查询的数据要映射的实体类的类型

子标签:

  • id:设置主键的映射关系
  • result:设置普通字段的映射关系
  • association:设置多对一的映射关系
  • collection:设置一对多的映射关系

属性:

  • property:设置映射关系中实体类中的属性名
  • column:设置映射关系中表中的字段名
    

        

        
        
        
        
    

    
        select * from t_emp left join t_dept on t_emp.did = t_dept.did
        where t_emp.eid = #{eid}
    

方案二:通过association处理映射关系

association属性:

  • property:设置映射关系中实体类中的属性名
  • column:指定表中对应字段
  • javaType: 指定映射到实体对象属性的类型
  • select:指定引入嵌套子查询的子SQL语句,用于关联映射中的嵌套查询
  • fetchType:指定在关联查询时是否启用延迟加载
 
        
        
        
        
        

        
            
            
        

    

    
        select * from t_emp where eid = #{eid}
    

2、根据员工所对应的部门id查询部门信息

public interface DeptMapper {

    //分步查询查询员工信息以及员工所对应的部门信息
    //第二步 通过did查询员工所对应的部门信息
    Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);
}

DeptMapper.xml






    
        select * from t_dept left join t_emp on t_dept.did = t_emp.did
        where t_dept.did = #{did}
    

方案二:分步查询

 1、询部门信息

public interface DeptMapper {

    //分步查询部门以及部门中所有员工的信息
    //第一步 查询部门信息
    Dept getDeptAndEmpByStepOne(@Param("did") Integer did);
}

DeptMapper.xml

    
        
        
        
        
    

    
        select * from t_emp where did = #{did}
    

查询结果:

十、动态SQL
  • Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能
  • 它存在的意义是为了解决拼接SQL语句字符串时的痛点问题

1、if

if:根据标签中text属性所对应的表达式决定标签中的内容是否需要拼接到SQL中

DynamicSQLMapper

public interface DynamicSQLMapper {
    //多条件查询
    List getEmpByCollection(Emp emp);
}

DynamicSQLMapper.xml






    
        select * from t_emp
        
            
                emp_name = #{empName}
            
            
                and age = #{age}
            
            
                and sex = #{sex}
            
            
                and email = #{email}
            
        
    

执行结果: 

3、trim

trim属性:

  • prefix:将 trim 标签中内容前面添加指定内容
  • prefixOverrides:在trim标签中的内容前面去掉某些内容
  • suffix:将 trim 标签中内容后面添加指定内容
  • suffixOverrides:在 trim 标签中的内容后面去掉某些内容

若标签中没有任何内容 trim 标签没有任何效果

 
    
        select * from t_emp
        
            
                
                    emp_name=#{empName}
                
                
                    age=#{age}
                
                
                    sex=#{sex}
                
                
                    email=#{email}
                
                
                
                    did = 1
                
            
        
    
 @Test
    public void testGetEmpByChoose(){
        SqlSession sqlSession= SqlSessionUtils.getSqlSession();
        DynamicSQLMapper dynamicSQLMapper =sqlSession.getMapper(DynamicSQLMapper.class);
        List list =dynamicSQLMapper.getEmpByChoose(
                new Emp(null,"张三",32,"男","123@qq.com"));
        System.out.println(list);
    }

多个条件成立,拼接第一个成立的 when 中的内容

 所有条件都不成立,拼接 otherwise 中的内容

5、foreach

foreach属性:

  • collection:设置需要循环的数组或集合
  • item:表示数组或集合中的每一个数据
  • separator:循环体之间的分隔符
  • open:foreach标签所循环的所有内容的开始符
  • close:foreach标签所循环的所有内容的结束符

通过数组实现批量删除

public interface DynamicSQLMapper {

    //通过数组实现批量删除
    int deleteMoreByArray(@Param("eids") Integer[] eids);
}

在数据表t_emp中增加几条测试数据

 DynamicSQLMapper.xml中加入

    
        delete from t_emp where eid in
        (
        
            #{eid}
        
        )
    
@Test
    public void testDeleteMoreByArray(){
        SqlSession sqlSession= SqlSessionUtils.getSqlSession();
        DynamicSQLMapper dynamicSQLMapper =sqlSession.getMapper(DynamicSQLMapper.class);
        int result=dynamicSQLMapper.deleteMoreByArray(new Integer[]{6,7,8});
        System.out.println(result);

    }

执行结果:

通过集合批量添加 

public interface DynamicSQLMapper {

    //通过list集合实现批量添加
    int insertMoreByList(@Param("emps") List emps);
}

DynamicSQLMapper.xml中加入


    insert into t_emp values
    
        (null,#{emp.empName},#{emp.age},#{emp.sex},#{emp.email},null)
    
    @Test
    public void testInsertMoreByList(){
        SqlSession sqlSession= SqlSessionUtils.getSqlSession();
        DynamicSQLMapper dynamicSQLMapper =sqlSession.getMapper(DynamicSQLMapper.class);
        Emp emp1=new Emp(null,"小刘",22,"男","12345@qq.com");
        Emp emp2=new Emp(null,"小吴",26,"女","12345@qq.com");
        Emp emp3=new Emp(null,"小何",21,"男","12345@qq.com");
        List list=Arrays.asList(emp1,emp2,emp3);
        int result=dynamicSQLMapper.insertMoreByList(list);
        System.out.println(result);
    }
}

执行结果:

6、SQL片段
  • sql片段,可以记录一段公共sql片段,在使用的地方通过include标签进行引入
  • sql标签设置sql片段 如: eid,emp_name,age,sex,email 
  • include标签引入sql片段 如:
    
        eid,emp_name,age,sex,email
    

    
    
        select * from t_emp where eid = #{eid}
    
public class CacheMapperTest {

    @Test
    public void testCache(){
        SqlSession sqlSession= SqlSessionUtils.getSqlSession();
        CacheMapper cacheMapper=sqlSession.getMapper(CacheMapper.class);
        Emp emp = cacheMapper.getEmpByEid(1);
        System.out.println(emp);
    }
}

执行结果:

 增加一个查询,再查询一次相同的数据

 结果只输出一条SQL语句,说明第二次查询没有执行SQL,是从缓存中获取数据

 一级缓存失效的四种情况:
  1. 不同的SqlSession对应不同的一级缓存
  2. 同一个SqlSession但是查询条件不同
  3. 同一个SqlSession两次查询期间执行了任何一次增删改操作
  4. 同一个SqlSession两次查询期间手动清空了缓存 SqlSession.clearCache()

2、Mybatis的二级缓存
  • 二级缓存需要手动开启
  • 二级缓存是SqlSessionFactory级别
  • 通过同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存
  • 此后若再次执行相同的查询语句,结果就会从缓存中获取

开启二级缓存
  1. 在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置
  2. 在映射文件中设置标签 cache
  3. 二级缓存必须在SqlSession关闭或提交之后有效 SqlSession.commit() SqlSession.close()
  4. 查询的数据所转换的实体类类型必须实现序列化的接口 implements Serializable

   @Test
    public void testTwoCache(){
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            SqlSession sqlSession1=sqlSessionFactory.openSession(true);
            CacheMapper cacheMapper1=sqlSession1.getMapper(CacheMapper.class);
            System.out.println(cacheMapper1.getEmpByEid(1));
            sqlSession1.close();
            SqlSession sqlSession2=sqlSessionFactory.openSession(true);
            CacheMapper cacheMapper2=sqlSession2.getMapper(CacheMapper.class);
            System.out.println(cacheMapper2.getEmpByEid(1));
            sqlSession2.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

执行结果:

二级缓存失效的情况:

两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效

二级缓存相关配置--cache标签中的属性

eviction:

  • LRU(Least Recently Used) – 最近最少使用的:移除最长时间不被使用的对象
  • FIFO(First in First out) – 先进先出:按对象进入缓存的顺序来移除它们
  • SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象
  • WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象
  • 默认是 LRU

flushInterval:

  • 刷新间隔,单位毫秒
  • 默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新

size:

  • 引用数目,正整数
  • 代表缓存最多可以存储多少个对象,太大容易导致内存溢出

readOnly:true/false

  • true:只读缓存
  • 会给所有调用者返回缓存对象的相同实例,调用者只能读不能写
  • false:读写缓存
  • 会返回缓存对象的拷贝(通过序列化)会慢一些,但是安全,默认是 false

3、Mybatis缓存的查询顺序

二级缓存对应多个SqlSession,一级缓存对应一个SqlSession

一级缓存和二级缓存同时有效,先搜索大范围在搜索小范围

  • 先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用
  • 如果二级缓存没有命中,再查询一级缓存
  • 如果一级缓存也没有命中,则查询数据库
  • SqlSession关闭之后,一级缓存中的数据会写入二级缓存

十二、Mybatis的逆向工程

正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表。

逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源:

  • Java实体类
  • Mapper接口
  • Mapper映射文件

1、创建逆向工程的步骤

①新建一个空项目 Mybatis_MBG

②添加依赖插件

  
    
        
            org.mybatis
            mybatis
            3.5.7
        
    
    
    
        
        
            
            
                org.mybatis.generator
                mybatis-generator-maven-plugin
                1.3.0
                
                
                    
                    
                        org.mybatis.generator
                        mybatis-generator-core
                        1.3.2
                    
                    
                    
                        com.mchange
                        c3p0
                        0.9.2
                    
                    
                    
                        mysql
                        mysql-connector-java
                        5.1.8
                    
                
            
        
    

③创建MyBatis的核心配置文件

④创建逆向工程配置文件,文件名必须是 generatorConfig.xml




    
    
        
        
        
        
        
            
            
        
        
        
            
        
        
        
            
        
        
        
        
        

⑤双击执行mybatis-generator插件

生成效果:

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号