Mybatis的二级缓存配置非常简单,只需要在mapper.xml中添加一句
<cache />
如果需要跟详细的配置可以配置其属性
<mapper namespace="com.*****">
<cache
eviction="LRU"
flushInterval="60000"
size="1024"
readOnly="true"
/>
...
</mapper>
eviction是缓存的淘汰算法,可选值有"LRU"、"FIFO"、"SOFT"、"WEAK",缺省值是LRU
flashInterval指缓存过期时间,单位为毫秒,60000即为60秒,缺省值为空,即只要容量足够,永不过期
size指缓存多少个对象,默认值为1024
readOnly是否只读,如果为true,则所有相同的sql语句返回的是同一个对象(有助于提高性能,但并发操作同一条数据时,可能不安全),如果设置为false,则相同的sql,后面访问的是cache的clone副本。
还有关于二级缓存的不足,下面是例子:
现有AMapper.xml中定义了对数据库表 ATable 的CRUD操作,BMapper定义了对数据库表BTable的CRUD操作,假设 MyBatis 的二级缓存开启,并且 AMapper 中使用了二级缓存,AMapper对应的二级缓存为ACache;除此之外,AMapper 中还定义了一个跟BTable有关的查询语句,类似如下所述:
<select id="selectATableWithJoin" resultMap="BaseResultMap" useCache="true">
select * from ATable left join BTable on ....
</select>
执行以下操作: 1. 执行AMapper中的"selectATableWithJoin" 操作,此时会将查询到的结果放置到AMapper对应的二级缓存ACache中 2. 执行BMapper中对BTable的更新操作(update、delete、insert)后,BTable的数据更新 3. 再执行1完全相同的查询,这时候会直接从AMapper二级缓存ACache中取值,将ACache中的值直接返回
好,问题就出现在第3步上:
由于AMapper的“selectATableWithJoin” 对应的SQL语句需要和BTable进行join查找,而在第 2 步BTable的数据已经更新了,但是第 3 步查询的值是第 1 步的缓存值,已经极有可能跟真实数据库结果不一样,即ACache中缓存数据过期了!
总结来看,就是: 对于某些使用了 join连接的查询,如果其关联的表数据发生了更新,join连接的查询由于先前缓存的原因,导致查询结果和真实数据不同步;