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
設置不緩存該查詢數據