mybatis二级缓存
Mybatis中一级缓存 和 二级缓存的区别
两者区别:一级缓存的作用域是在SqlSession中,二级缓存的作用域是针对mapper做缓存。
一级缓存(本地缓存)
一级缓存是框架默认为我们开启的,我们不需要做任何配置。
例如我们首次查询id为1的用户,mybatis会将该用户的对象存储在一级缓存中;
如果在此中间 sqlSession 执行了commit操作(增删改) ,则mybatis会清空一级缓存的数据 ,这样就能让我们的数据是最新的,避免产生脏读。
当我们再次查 id 为 1 的用户时,mybatis就会去缓存中查找,就不需要再从数据库中去查询。
mybatis一级缓存是默认开启的,是SqlSession级别的缓存,在操作数据库的时候需要创建一个SqlSession,其中有一个HashMap,用于存储缓存数据。不同的SqlSession之间,其缓存数据的HashMap是不同的;
所以当我们多次调用同一个Mapper和同一个方法的同一个参数,只会进行一次数据库查询,然后把数据缓存到缓冲中,以后直接先从缓存中取出数据,不会直接去查数据库。但是不同的SqlSession对象,因为不同的SqlSession都是相互隔离的,所以相同的Mapper、参数和方法,他还是会再次发送到SQL到数据库去执行,返回结果。所以我们需要根据需求开启二级缓存
二级缓存(全局缓存)
二级缓存是 mapper 级别的缓存,多个sqlSession去操作同一个Mapper的sql,不管Sqlsession 是否相同,只要 mapper 的 namespace相同就能共享数据。也可以称之为 namespace 级别的缓存 。
sqlSession 关闭后(close) ,一级缓存的数据会保存到二级缓存中,新的相同的查询语句就会去二级缓存中去查询。
二级缓存是Mapper级别的缓存,多个SqlSession去操作同一个Mapper中的SQL语句,则这些SqlSession可以共享二级缓存,即二级缓存是跨SqlSession的。
二级缓存开启
1,xml 配置中开启 二级缓存
<settings>
<!-- 开启二级缓存(默认是开的,这里写出来是为了方便代码维护) -->
<setting name="cacheEnabled" value="true" />
</settings>
2,去mapper映射文件中使用二级缓存
<!-- 开启本mapper所在namespace的二级缓存 -->
<cache />
3,需要将要存储数据的 pojo 实现 Serializable接口,为了将数据取出做反序列化操作, 因为二级的缓存的存储方式多种多样,有可能存储在内存中,也可能储存到磁盘中。如果我们要再取这个缓存的话,就需要反序列化了。所以建议mybatis中的pojo都去实现Serializable接口。
mybatis解读
1、开启缓存的弊端是数据没有实时性,当数据库中的数据一旦修改,查询的数据还是缓存中的数据没有实时性,对于某些需要实时性显示数据的接口我们可以设置 useCache=“false” ,设置该属性后,该接口每次查询出来都是去执行sql查询出实时性数据。如:
<select id="findArtPageview" parameterType="com.Article" resultType="int" useCache="false">
select pageview from article where aid=#{aid}
</select>
设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。所以:针对每次查询都需要最新的数据sql,要设置成useCache=false,禁用二级缓存。
2、清空缓存,一般下执行完commit操作都需要刷新缓存,flushCache=true表示刷新缓存,这样可以避免数据库脏读。但是如果你不想刷新缓存只需要这么做:
<update id="pageviewAdd" parameterType="com.Goods" flushCache="false">
update goods set pageview=#{pageview} where gid=#{gid}
</update>
将flushCache=true改为flushCache=false就不用刷新了
总结
1、当为select语句时:
flushCache默认为false,表示任何时候语句被调用,都不会去清空本地缓存和二级缓存。
useCache默认为true,表示会将本条语句的结果进行二级缓存。
2、当为insert、update、delete语句时:
flushCache默认为true,表示任何时候语句被调用,都会导致本地缓存和二级缓存被清空。
useCache属性在该情况下没有。
当为select语句的时候,如果没有去配置flushCache、useCache,那么默认是启用缓存的,所以,如果有必要,那么就需要人工修改配置。