延迟加载
- 默认不打开延迟加载
- 没有管理关联关系的对象,不会有代理对象
<settings>
<!--打开延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--按需加载-->
<setting name="aggressiveLazyLoading" value="false"/>
<!--会导致实例化的方法-->
<setting name="lazyLoadTriggerMethods" value="clone"/>
</settings>
情况1:不配置以上三个属性: 每次调用mapper方法,都是迫切加载
情况2:仅仅配置打开延迟加载: 查询员工,只发送查员工的sql,但只要调用员工任意方法,都会发查询部门属性的sql.
情况3:打开延迟加载+按需加载,只有使用到员工的部门属性(包括id),才会发查部门的sql
情况4:默认会实例化的方法:equals,clone,hashCode,toString.
与Hibernate的延迟加载区别
- Hibernate中,员工对象的dept属性为代理对象,访问其非主键属性才会实例化
- myBatis中,员工对象为代理对象,dept为原本的类的对象.
mybatis的缓存机制
1.一级缓存
连续两次查询一个对象或list,会只发送一条sql,第二次查询会从一级缓存中提取.
在mybatis中,对一级缓存的操作只有一个.
session.clearCache()
清除全部的一级缓存.
2.自带的二级缓存
1.使用自带的二级缓存
- 默认二级缓存是开启的,但是需要在映射文件中声明使用
- domain类必须实现序列化接口 serializable
- 开启二级缓存后,该映射的所有select都会享受缓存待遇.
- 对表的任意操作,都会导致缓存的清除(查1,添加新的此时缓存清除,再查1)
<!--在映射文件的根节点mapper中-->
<cache/>
2.自带的二级缓存的增强
- 在修改和删除时候,依然需要清空自带二级缓存
- 在新增时候,不需要清空自带二级缓存 flushCache=”false”(默认true)
- 在获取单个时候,设置开启二级缓存(打开
<cache>
就默认打开所有select的缓存) - 在获取list,设置不需要存入二级缓存,
<!--添加对象,不清空二级缓存-->
<insert id="add" flushCache="false">
<!--查询一个对象,存入缓存(可省)-->
<select id="get" useCache="true">
<!--查询多个对象,不存入缓存-->
<select id="list" useCache="false">
3.第三方的二级缓存(ehcache)
1.导入包
2.常见缓存参数配置
- maxElementsInMemory:最多缓存个数
- eternal:是否永久有效(默认缓存为false,若为true,后面配置无效)
- timeToIdleSeconds:过多久,且空闲,就删除
- timeToLiveSeconds:过多久,就删除
- overflowToDisk:当缓存满了,是否保存到临时磁盘.
3.ehcache.xml文件
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<!-- 默认缓存设置 -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
<!-- 自定义缓存设置 -->
<cache name="myCache"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="true"
/>
</ehcache>
4.使用缓存
<!--会先跟命名空间的值匹配对应的缓存池,匹配不到就选默认的-->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
5.映射文件中的cache标签的属性
- size:该对象最大存放个数
- flushinterval:固定刷新缓存的
- eviction:剔除缓存的策略
6.二级缓存在java代码中的操作
- 添加新对象时候,依然要在insert标签中加入flushCache=”false”
- 在修改或删除时候,也加入flushCache=”false”的属性
修改或删除对象时候,代码中获取缓存对象,删除对应的单个缓存,不用清空全部缓存
<!--添加增删改,不清空二级缓存--> <insert id="add" flushCache="false"> <update id="update" flushCache="false"> <delete id="delete" flushCache="false">
//通过映射文件的命名空间获取对应的缓存对象 //删除和关系时候,可以操作对应的缓存中的数据 Cache cache = session.getConfiguration().getCache("com.lwf.mybatis.hallo.UserMapper"); cache.clear();//清空全部缓存 cache.putObject(arg0, arg1);//放入一个缓存 cache.removeObject(arg0);//清除一个缓存