前言
mybatis提供查询缓存,用于减轻数据压力,提高数据库性能。
mybaits提供一级缓存,和二级缓存。
一级缓存
一级缓存默认开启。
一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。
二级缓存
首先开启mybatis的二级缓存.
在核心配置文件SqlMapConfig.xml中加入
在UserMapper.xml中开启二缓存,UserMapper.xml下的sql执行完成会存储到它的缓存区域(HashMap
1 | <mapper namespace="com.iot.mybatis.mapper.UserMapper"> |
二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
每一个namespace的mapper都有一个二缓存区域。
局限性和分布式问题
局限性
mybatis二级缓存对细粒度的数据级别的缓存实现不好。
比如如下需求:对商品信息进行缓存,由于商品信息查询访问量大,但是要求用户每次都能查询最新的商品信息,此时如果使用mybatis的二级缓存就无法实现当一个商品变化时只刷新该商品的缓存信息而不刷新其它商品的信息,因为mybaits的二级缓存区域以mapper为单位划分,当一个商品信息变化会将所有商品信息的缓存数据全部清空。解决此类问题需要在业务层根据需求对数据有针对性缓存。
分布式问题
无论是一级缓存还是二级缓存,都是本地缓存,对分布式来说,都很难保持一致性,所以分布式环境下,最好不使用Mybatis的缓存,或者使用EnChache等分布式缓存框架,搭建分布式缓存。
一级缓存默认打开,且截至目前我们无法关闭,我们可以有两种方式解决这个问题:
- 可以设置Mybatis一级缓存为STATEMENT级别,因为在查询方法执行的最后,会判断一级缓存级别是否是STATEMENT级别,如果是的话,就清空缓存。
- select标签里面设置flushCache=”true”即可