Mybatis缓存分为一级缓存和二级缓存
-
MyBatis一级缓存是默认开启的,数据存储范围是SqlSession会话这个级别,当SqlSession关闭后,缓存就会被清除,生命周期非常短。
-
MyBatis二级缓存需手动开启,二级缓存存储范围为Mapper Namespace(Mapper映射器的命名空间)
MyBatis缓存数据是存储在JVM内存中,它存储对象的本质是利用Map保存缓存数据。
二级缓存运行规则:
- 二级缓存开启后,默认所有的查询操作均使用缓存
- 写/插入操作commit提交时,对namespace缓存强制清空
- 在select/update/insert/delete标签中,配置useCache=false代表不使用缓存,默认为true
- 在select/update/insert/delete标签中,配置flushCache=true代表强制清空缓存,默认为false
@Test
public void demo(){
SqlSession sqlSession = null;
try{
sqlSession = MyBatisUtils.openSession();
//从数据库中获取数据,并放入缓存
Blog blog = sqlSession.selectOne("queryBlogById", 45);
//从缓存中获取数据
Blog blog1 = sqlSession.selectOne("queryBlogById", 45);
/* 对比两个会话的内存地址 */
System.out.println(blog.hashCode() + " : " + blog1.hashCode());
}catch (Exception e){
throw e;
}finally {
MyBatisUtils.closeSession(sqlSession);
}
}
开启MyBatis二级缓存
通过在mapper映射器文件中配置<cache/>标签来开启二级缓存:
eviction属性是缓存的清除策略,当缓存对象数量达到上限时,自动触发MyBatis对应的算法清除缓存对象
LUR - 最近最少使用的:移除最长时间不被使用的对象(建议使用)
FIFO - 先进先出:按照对象进入缓存的顺序来移除它们
SOFT - 软引用:移除基于垃圾回收器状态和软引用规则的对象
WEAK - 弱引用:更积极地移除基于垃圾回收器状态和弱引用规则的对象
flushInterval属性代表间隔多长时间自动清除缓存,单位毫秒,600000 = 10分钟
size属性缓存存储对象或对象集合(一个对象集合算一个对象)数目上限,个人不建议对对象集合进行缓存
readOnly属性: 设置为true,代表返回只读缓存,每次从缓存中取出的是缓存对象本身,执行效率高(建议使用)
设置为false,代表每次取出的是缓存对象的“副本”,每次取出的对象都是不同的,安全性较高
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cd.blog.dao.BlogDao">
<!--开启二级缓存:
eviction是缓存的清除策略,当缓存对象数量达到上限时,自动触发MyBatis对应的算法清除缓存对象
LUR - 最近最少使用的:移除最长时间不被使用的对象
FIFO - 先进先出:按照对象进入缓存的顺序来移除它们
SOFT - 软引用:移除基于垃圾回收器状态和软引用规则的对象
WEAK - 弱引用:更积极地移除基于垃圾回收器状态和弱引用规则的对象
flushInterval代表间隔多长时间自动清除缓存,单位毫秒,600000 = 10分钟
size缓存存储对象或对象集合(一个对象集合算一个对象)数目上限,个人不建议对对象集合进行缓存
readOnly:
设置为true,代表返回只读缓存,每次从缓存中取出的是缓存对象本身,执行效率高
设置为false,代表每次取出的是缓存对象的“副本”,每次取出的对象都是不同的,安全性较高-->
<cache type="LUR" flushInterval="600000" size="512" readOnly="true"/>
<select id="selectById" parameterType="Integer" resultType="Blog">
select *from t_blog where blog_id = #{blogId}
</select>
<!--配置useCache="false"属性,代表该查询的数据不被放入缓存-->
<select id="selectAll" resultType="Blog" useCache="false">
select *from t_blog
</select>
<!--配置flushCache="true"属性,代表执行完update语句后立马清空缓存,而不是等到commit提交后-->
<update id="updateBlog" parameterType="Blog" flushCache="true">
UPDATE t_blog
<set>
<if test="title != null">title = #{title},</if>
<if test="content != null">content = #{content},</if>
<if test="description != null">description = #{description},</if>
</set>
WHERE blog_id = #{blogId}
</update>
<!--配置flushCache="true"属性,代表执行完insert语句后立马清空缓存,而不是等到commit提交后-->
<insert id="insertBlog" keyColumn="blog_id" keyProperty="blogId" useGeneratedKeys="true" parameterType="Blog" flushCache="true">
INSERT INTO t_blog
(
title, content, description
)
VALUES
(
#{title}, #{content}, #{description}
)
</insert>
</mapper>
二级缓存总结
1. MyBatis二级缓存需手动开启,二级缓存存储范围为Mapper Namespace(Mapper映射器的命名空间),而一级缓存是默认开启的,数据存储范围是SqlSession会话这个级别,当SqlSession关闭后,缓存就会被清除,生命周期非常短。
2. 二级缓存开启后,默认所有的查询操作均使用缓存。如果不想对查询结果缓存,可以在select标签中配置useCache=false设置不缓存查询结果
3. 建议只对查询单个对象的数据进行缓存,不对那些对象集合进行缓存,因为当一个对象集合中保存的对象很多的时候,就会消耗很多的内存。所以针对selectAll这种类型的查询结果时,建议配置useCache=false
设置不缓存该查询数据