mybatis中的查询缓存

转载自:https://www.cnblogs.com/zhangzongle/p/6211285.html

查询缓存

 Mybatis提供查询缓存,用于减轻数据压力,提高数据库压力。

 Mybatis提供一级缓存和二级缓存。

mybatis中的查询缓存_第1张图片

在操作数据库时需要构造SqlSession对象,在对象中有一个数据结构(HashMap)用于缓存数据。

  不同的SqlSession之间的缓存数据区域是互相不影响的。

  Mybatis一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。

  Mybatis二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。

1、一级缓存

mybatis中的查询缓存_第2张图片

第一次发起查询,先去找缓存中是否有id为1的用户信息,如果没有,从数据库中查询用户信息。

  得到用户信息,将用户信息存储到一级缓存中。

  第二次发起查询用户id为1的用户信息,先去缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。

  如果SqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存。目的是为了让缓存中存储的是最新的信息,避免脏读。

  Mybatis默认支持一级缓存,不需要在配置文件中配置。

  Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象。

应用场景:
mybatis中的查询缓存_第3张图片

2、二级缓存

mybatis中的查询缓存_第4张图片

SqlSession1去查询用户id为1的用户信息,查询到用户信息会将查询数据存储到二级缓存中。

  SqlSession2去查询用户id为1的用户信息,去缓存中找是否存在数据,如果存在直接从缓存中取出数据。

  二级缓存区域是根据mapper的namespace划分的,相同namespace的mapper查询数据放在同一个区域,如果使用mapper代理方法每个mapper的namespace都不同,此时可以理解为二级缓存区域是根据mapper划分。

每次查询会先从缓存区域找,如果找不到从数据库查询,查询到数据将数据写入缓存。

  Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象

  sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。

开启二级缓存:

1、在核心配置文件mybatis-config.xml中加入

"cacheEnabled" value="true"/>

mybatis中的查询缓存_第5张图片

2、 要在你的Mapper映射文件中添加一行: ,表示此mapper开启二级缓存。

3、二级缓存需要查询结果映射的pojo对象实现java.io.Serializable接口实现序列化和反序列化操作,注意如果存在父类、成员pojo都需要实现序列化接口。

为了将缓存数据取出执行反序列化,因为二级缓存存储介质多种多样,不一定在内存。

禁用二级缓存:

  在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。

<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">

刷新缓存(就是清空缓存):

  设置statement配置中的flushCache=”true” 属性,默认情况下为true即刷新缓存,如果改成false则不会刷新。使用缓存时如果手动修改数据库表中的查询数据会出现脏读。

<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">

应用场景:

  对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用mybatis二级缓存技术降低数据库访问量,提高访问速度,业务场景比如:耗时较高的统计分析sql、电话账单查询sql等。

  实现方法如下:通过设置刷新间隔时间,由mybatis每隔一段时间自动清空缓存,根据数据变化频率设置缓存刷新间隔flushInterval,比如设置为30分钟、60分钟、24小时等,根据需求而定。

局限性:

  mybatis二级缓存对细粒度的数据级别的缓存实现不好,比如如下需求:对商品信息进行缓存,由于商品信息查询访问量大,但是要求用户每次都能查询最新的商品信息,此时如果使用mybatis的二级缓存就无法实现当一个商品变化时只刷新该商品的缓存信息而不刷新其它商品的信息,因为mybaits的二级缓存区域以mapper为单位划分,当一个商品信息变化会将所有商品信息的缓存数据全部清空。解决此类问题需要在业务层根据需求对数据有针对性缓存。

你可能感兴趣的:(mybatis)