mybatis一级缓存的实现及其问题

发布时间 2024-01-12 16:01:51作者: zhjh256

一级缓存的特性是:

1,一级缓存模式是开启状态(可通过localCacheScope属性控制,默认为SESSION,开启)
2,一级缓存作用域在于SqlSession(大家可以关闭SqlSession,然后创建一个新的,再获取对象,观察实验结果),缓存随着会话(SqlSession)的创建而产生,随着会话结束而释放(使用spring托管的mybatis后,session是会自动关闭的,参见https://www.cnblogs.com/zhjh256/p/12434447.html,在非spring托管时是需要人工关闭的,否则会导致连接泄漏)。对一次会话的查询操作,总是先查看缓存中是否存在查询结果,如果存在则直接取缓存中的结果,不存在则查询数据库。这样的话,一次会话中的完全相同的查询则只会查询一次,节省了系统资源。
3,如果中间有对数据的更新操作,则将清空一级缓存。

如下:

 

 

 

 

 

 一级缓存的最大缺点在于只能用于只有一个会话的应用,如果是分布式应用或并发应用,如果在sqlsession期间,其他节点、连接更新了数据库或数据库中直接进行了更新,取到的是缓存的旧信息,对于人工管理的sqlsession更是如此,会导致逻辑错误。因此,最好的方法是禁用一级缓存,启用二级缓存。

 

二级缓存通过<setting name="cacheEnabled" value="true"/>控制,也支持mapper级别配置。

默认的二级缓存配置会有如下特点:
2.1 所有的Select语句将会被缓存
2.2 所有的更新语句(insert、update、delete)将会刷新缓存
2.3 缓存将采用LRU(Least Recently Used 最近最少使用)算法来回收
2.4 缓存会存储1024个对象的引用
回收算法建议采用LRU,当然,还提供了FIFO(先进先出),SOFT(软引用),WEAK(弱引用)等其他算法。

 

 

 

二级缓存关键说明:

当关闭了SqlSession之后,才会将查询数据保存到二级缓存中(SqlSessionFactory)中,所以才有了上述的缓存命中率。MyBatis的二级缓存默认采用的是Map的实现。

对原理的解析可以参见https://blog.csdn.net/luanlouis/article/details/41280959。