MyBatis延迟加载,缓存的使用

一.什么是延迟加载?

延迟加载也称为懒加载,是指在进行关联查询时,按照设置延迟加载规则推迟对关联对象的select查询,可以有效减少数据库压力

延迟加载默认是关闭的,这个时候走的是直接加载,使用延迟加载需要在大配置中开启延迟加载

    <!--延迟加载是否开启-->
       <setting name="lazyLoadingEnabled" value="true"></setting>

延迟加载分为三种:

1.直接加载

执行完select查询后,马上执行关联对象的select查询

2.侵入式延迟加载

执行对主加载对象的查询时,不会执行对关联对象的查询

3.深度延迟加载

执行对主加载对象的查询时,不会执行对关联对象的查询,访问主加载对象详情时,也不会执行关联对象的select查询,只有当真正访问关联对象详情时,

才会执行对关联对象的select查询 

       <!-- true false 深度延迟加载-->
       <!--true true 侵入式延迟加载 -->
       <!--false true 直接加载-->
       <setting name="lazyLoadingEnabled" value="true"></setting>
       <setting name="aggressiveLazyLoading" value="false"></setting>

下边是一个例子:

   /*
    * 延迟加载  只能用于多条SQL 单条SQL不可以
    * */
    @Test
    public void test10(){
        SqlSession sqlSession= MyBatisUtil.getSession();
        IdeptDao mapper = sqlSession.getMapper(IdeptDao.class);
        //直接加载  执行select语句  此时lazyLoadingEnabled是关闭的  false
        dept all = mapper.findAllMoreDeptName(1);
        //执行对关联对象的查询时  才会执行侵入式加载
        System.out.println(all.getDeptName());
        //当真正访问对关联对象的详情的时候  用到深度延迟加载
        for (emp item :all.getEmps()){
            System.out.println(item.getEmpName());
        }
        sqlSession.close();
    }
 

 二.MyBatis缓存

分为一级缓存和二级缓存

缓存的开启

一级缓存存在性的证明:

 <!--一级缓存 在MyBatis中一级默认是内置的,不能卸载
只能在一个线程之间使用数据,当sqlsession一旦关闭之后,缓存中的数据就会消失
增删改对一级缓存的影响
增删改操作会将一级缓存清空
--> 
  //一级缓存的存在证明
    @Test
    public void test15(){
        SqlSession sqlSession= MyBatisUtil.getSession();
        IdeptDao mapper = sqlSession.getMapper(IdeptDao.class);
        dept all = mapper.findAllMoreDeptName(1);
        System.out.println(all.getDeptName());
       //增加  增删改方法会对一级缓存进行清空  在分割线下边在进行查询的时候就会重新发送SQL语句
        dept dep=new dept();
        dep.setDeptName("运营一部");
        mapper.add(dep);
        sqlSession.commit();
        System.out.println("====我是高贵的分割线====");
        dept all2 = mapper.findAllMoreDeptName(1);
        System.out.println(all2.getDeptName());
        sqlSession.close();
    }

控制台打印出来的效果:

在运行了add()方法之后,一级缓存将进行清空,在调用上边的方法时,将从缓存中拿不到数据,此时将会重新发送SQL语句

二级缓存:

二级缓存的配置需要三个条件:

1.在大配置中开启二级缓存,书写一个节点

<setting name="cacheEnabled" value="true"></setting>

2.实体类实现接口Serializable

3.在映射文件中加<cache/>标签

<!--二级缓存-->
<!--二级缓存 默认是开启的 true
一旦开启
可以在多个线程之间共享数据 相同的SQL语句在二次查询是直接从缓存中读取,sqlsession关闭后,也可以共享数据-->

    //二级缓存
    @Test
    public void test11(){
        SqlSession sqlSession= MyBatisUtil.getSession();
        IdeptDao mapper = sqlSession.getMapper(IdeptDao.class);
        dept all = mapper.findAllMoreDeptName(1);
        System.out.println(all.getDeptName());
        sqlSession.close();
        System.out.println("====我是高贵的分割线====");
        SqlSession sqlSession2= MyBatisUtil.getSession();
        IdeptDao mapper2 = sqlSession2.getMapper(IdeptDao.class);
        dept all2 = mapper2.findAllMoreDeptName(1);
        System.out.println(all2.getDeptName());
        sqlSession.close();
    }

下边是控制台打印的结果:

方法内部已经关闭了sqlsessin,但是开启了二级缓存,所以说再次调用方法时,不用再次发送SQL语句,直接从二级缓存中读取

原文地址:https://www.cnblogs.com/1234AAA/p/8480398.html