延迟加载 lazyLoadingEnabled
定义: MyBatis中的延迟加载也成为懒加载,就是在进行关联查询的时候按照设置延迟加载规则推迟对关联对象的select检索。延迟加载可以有效的减少数据库的压力。延迟加载只对关联对象的查询有延迟设置,对于主加载对象都是直接执行查询语句的。
时机:1.直接加载
2.侵入式延迟加载(aggressiveLazyLoading) 也可看做立即加载
3..深度延迟加载
直接加载:即执行对象的select语句完成对主加载马上执行对关联对象的select查询
侵入式延迟加载:执行对主加载对象的查询时,不会执行对关联对象的查询。但是当要访问主加载对象的详情时马上执行对关联对象的select查询。即对关联对象的执行查询,侵入到了主加载对象的访问详情中。也可理解为:将关联对象的详情侵入到主加载对象的详情中去,即将关联对象的详情作为主加载对象的一部分出现了!
深度延迟:执行对主加载对象的查询时,不会执行对关联对象的查询。访问主加载对象的详情时也不会执行关联对象的select查询。只有当真正访问关联对象的详情时,才会执行对关联对象的select查询
<settings> <!--开启延迟加载--> <setting name="lazyLoadingEnabled" value="true"></setting> <!--关闭侵入式延迟加载--> <setting name="aggressiveLazyLoading" value="false"></setting> </settings>
lazyLoadingEnabled : 默认为false 延迟加载的全局开关
aggressiceLazyLoading : 所谓侵入式加载,就是在启用时(true) 对任意加载属性的调用会使带有延迟加载属性的对象完整加载,反之,每种属性将会按照需要加载。默认为true
MyBatis缓存
使用缓存可以使应用更快地获取数据,避免和数据库的频繁地交互,尤其是在查询越多、缓存命中率越高的情况下,使用缓存的作用也就越明显。MyBatis作为持久性的ORM框架,提供了非常强大的查询缓存特性,可以非常方便的配置和使用。
在MyBatis中分为一级缓存和二级缓存,MyBatis缓存的作用域是在映射文件的namespace去划分的,相同namespace的mapper查询缓存放在相同的区域,反之放在不用的位置,且不同区域的缓存互不干扰。
其中一级缓存是在一次会话范围内有效,即同一个SqlSession范围内,而二级缓存是可以在不用同的Sqlsession中共享数据的。(证明一级缓存的存在,可以在同一个SqlSession中调用两次相同的查询语句,用log4j打印发送的SQL语句,如果只发送一条,证明一级缓存存在。log4j的配置文件可以上网找)
一级缓存是默认开启的无需进行配置,且在进行增删改操作的时候,同时会对缓存中的数据进行相同的操作,即缓存中的数据与数据库中的数据保持一致
MyBatis的二级缓存是一个外部的插件,使用二级缓存首先要导入依赖
1 <!--引入需要的ehcache插件--> 2 <dependency> 3 <groupId>net.sf.ehcache</groupId> 4 <artifactId>ehcache</artifactId> 5 <version>1.2.3</version> 6 </dependency> 7 <!--mybatis整合ehcache的jar--> 8 <dependency> 9 <groupId>org.mybatis</groupId> 10 <artifactId>mybatis-ehcache</artifactId> 11 <version>1.0.0</version> 12 </dependency>
其次需要一个配置文件:ehcache.xml(这个名字是固定的,想要改变那你就自己去改变源码中的数据)
以下是ehcache.xml文件中的属性
Ø maxElementsInMemory:在内存中最大的存储量
Ø eternal:是否在内存中永远不销毁
Ø timeToIdleSeconds:在缓存中闲置多少时间之后销毁,默认单位是S
Ø timeToLiveSeconds:在缓存中存活多少时间之后销毁,无论是否有人使用,默认单位是S
Ø overflowToDisk:当缓存满的时候是否保存到磁盘中
Ø diskPersistent:磁盘中的文件是否永久保存
Ø diskExpiryThreadIntervalSeconds:检测线程运行时间间隔!默认单位是S
Ø memoryStoreEvictionPolicy:缓存清理策略:
1.LRU(least recently used) 最近最少使用每个缓存的元素都有一个时间戳,当缓存容量满的时候,需要腾出来新位置给新缓存元素,这时候,会比较时间戳然后 删除符合条件的缓存元素
2.LFU (least frequently used )最少使用一直以来最少使用的缓存元素,缓存 元素中有一个hit值,hit值最少的将会清除!
3.FIFO(first in first out) 先进先出
<?xml version="1.0" encoding="UTF-8"?> <ehcache> <!--文件位于resources目录下--> <!--临时文件目录 可以自己设置--> <diskStore path="D:/"/> <!-- maxElementsInMemory:在内存中最大的存储量 eternal:是否在内存中永远不销毁 timeToIdleSeconds:在缓存中闲置多少时间之后销毁,默认单位是S timeToLiveSeconds:在缓存中存活多少时间之后销毁,无论是否有人使用,默认单位是S overflowToDisk:当缓存满的时候是否保存到磁盘中 diskPersistent:磁盘中的文件是否永久保存 diskExpiryThreadIntervalSeconds:检测线程运行时间间隔!默认单位是S memoryStoreEvictionPolicy : 缓存清理策略 1.LRU (least recently used) 最近最少使用 每个缓存的元素都有一个时间戳,当缓存容量满的时候,需要腾出来新位置给新缓存元素, 这时候,会比较时间戳然后删除符合条件的缓存元素 2.LFU (least frequently used )最少使用 一直以来最少使用的缓存元素,缓存元素中有一个hit值,hit值最少的将会清除! 3.FIFO(first in first out) 先进先出 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> </ehcache>
同时需要在映射文件中添加以下节点:
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
在全局配置文件中添加setting节点:
<!--开启二级缓存--> <setting name="cacheEnabled" value="true"></setting>
这样二级缓存就开启了,可以自行进行测试检查结果
结论:
Ø 二级缓存不比一级缓存,需要在configuration.xml中手动开启。
Ø 二级缓存是全局应用级别的缓存,即使关闭了session仍能使用。
Ø 如果一个select标签想要局部关闭二级缓存,需要设置useCache=false
Ø 二级缓存不能使用注解方法配置
Ø 如果在执行增删改操作的过程中不刷新缓存,须设置flushCache=false