一、先说说懒加载吧
为什么要用它?当嵌套查询多层的时候,数据量非常大,
而内存有限的情况下,使用它久能够节省内存.
怎么用?
设置在全局配置文件(mybatis-config.xml文件)的settings标签中
<settings>
<setting name="lazyLoadingEnabled" value="true"></setting>
<setting name="aggressiveLazyLoading" value="false"></setting>
</settings>
打开延迟加载的全局开关:设置lazyLoadingEnabled 为true
关闭积极加载的全局开关:设置aggressiveLazyLoading为false.
举个例子并且讲懒加载和积极加载做个对比.
这里是一个User表
这是一个Order表
很明显,Order中的外键是user_id,通过这个来进行关联.
再比如我们的需求是这个样子的:
对应的java Order对象是这样子,现在要通过订单number来进行查询Order,并且Order中还要有User.
但是数据库中我们的Order表中没有User,只有一个和它关联的外键.
对应的mapper接口
首先通过getOrdersByNumber查询到Orders的属性,再根据外键user_id,加载深层次的user属性,
它加载了另一个select语句.
比如这里查询的number为 1000010,使用log4j跟踪日志信息
可以看到执行了一次select后,返回了total为1,标识查询到一个结果
然后再执行一次更深层次的select.查找user 分为了两次
当关闭了懒加载,并且删除掉标签fetchType后,现在是默认的积极加载,
他会一次性加载出来结果
二、缓存机制
mybatis默认开启的是一级缓存,mapper级别的,
就是在不同sqlSession下所存储的缓存被其他sqlSession是看不到的.
要开启二级缓存必须做到两个:
1.返回的对象必须实现序列化
2.只需要在SQL配置文件中添加一个标签就行<cache
对于mapper.xml映射文件中的cache标签有如下几项配置,都是可选的
<eviction 清除策略,即在一个时间周期后,采用哪种清除策略.
默认是FIFO(先进先出),可供选择还有LRU(最近最少使用的) SOFT(Java的软引用) WEAK(Java的虚引用)
<flushInterval 时间间隔,多长时间刷新一次,毫秒为单位,默认不设置就是不刷新
<size 最大的引用数目,默认1024.
<readOnly 对于缓存中的数据只能可读形式,在多线程中比较安全. 默认是false
在mapper文件中开启了二级缓存后,所有的sqlSession之间共享数据,
并且每条SQL语句可以自定义是否使用二级缓存,是否刷新缓存.
<select ... flushCache="false" useCache="true"/>
<insert ... flushCache="true"/>
<update ... flushCache="true"/>
<delete ... flushCache="true"/>
演示一下:
查询表中id为1的用户
当开启了<cache 标签后,使用log4j打印出来的追踪信息是
可以看到Cache Hit Ratio 0.5,并且只执行了一次sql,第二次执行的时候直接在缓存中拿的
再接着看关闭二级缓存后,即取消掉<cache标签
它执行了两次SQL语句
再当这两次查询都在同一个sqlSession中的时候呢
只执行了一次SQL.另外记住了,update,delete,update操作会默认刷新缓存