MyBatis有多种提高查询效率的方法,比如说懒加载、缓存。MyBatis为我们提供了一级缓存和二级缓存。其中一级缓存是默认开启的,二级缓存需要我们自己去Mapper文件里配置。
一级缓存
一级缓存是SqlSession
级别的,而且是默认开启的(但是这里需要注意的是MyBatis和Spring整合之后,一级缓存就会失效,每调用一次Mapper里的方法,就会重新创建一个SqlSession
)。也就是说在同一个SqlSession里,相同的查询语句,第一次查询的结果会被缓存(PerpetualCache,缓存默认的实现类,包括一级缓存和二级缓存),后面的查询会直接从缓存里取数据。一级缓存里存的是上一次查询的对象,两个对象是完全相同
的。
代码示例1
1 | // 一级缓存默认开启,sqlsession级别 |
运行结果1
从运行结果可以看出,同一个SqlSession里,第一次查询的时候会把缓存数据,第二次查询的时候并没有去数据库里查询。不同的SqlSession之间缓存是不共享的。
代码示例2
1 | // 一级缓存默认开启,sqlsession级别 |
运行结果2
二级缓存
二级缓存默认是不开启的,并且二级缓存是基于 mapper 中的 namespace 的,也就是说就算是不同的sqlSession,如果namespace相同,那么还是可以共享缓存的。
开启二级缓存
设置 cacheEnable 属性值为 true
在对应的mapper xml文件里添加
<cache />
标签,PerpetualCache 是mybatis提供的默认缓存实现类,内部数据结构是HashMap。1
2> <cache type="org.apache.ibatis.cache.impl.PerpetualCache"></cache>
>
代码示例
1 | // 二级缓存默认不开启,需要去手动开启 |
运行结果
从上面的运行结果可以看出,二级缓存开启之后,messageDao2,messageDao3这两次查询都是从缓存里面去查找数据的,缓存命中率分别为0.5和0.66666666。sqlSession3修改数据之后并且commit,可以发现messageDao2并没有从缓存里面取出数据,而是从数据库里获取数据。
如何关闭一级缓存
- 设置
localCacheScope
为STATEMENT
级别,默认是SESSION
级别。 - 设置
flushCache
为true
。