一.什么是延迟加载?
延迟加载也称为懒加载,是指在进行关联查询时,按照设置延迟加载规则推迟对关联对象的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