MyBatis二级缓存

 一级缓存默认开启,缓存范围是SqlSession会话,二级缓存需手动开启,缓存范围是Mapper Namespace。在某个namespace中手动开启的二级缓存被所有SqlSession共享。二级缓存开启后默认所有查询操作均使用缓存,为保证数据的一致性,写操作commit提交时对该namespace缓存强制清空。

 配置useCache=false可以不用缓存

 配置flushCache=true代表强制清空缓存

<select id="selectById" parameterType="Integer" resultType="com.MyBatis.entity.Goods">
        select * from t_goods where goods_id = #{value}
</select>

验证一级缓存:

 在同一个SqlSession对象中,执行两次相同的查询操作

复制代码
@Test
    public void testlv1Cache(){
        SqlSession sqlSession=null;
        try{
            sqlSession=MyBatisUtils.openSession();
            Goods goods = sqlSession.selectOne("goods.selectById",1603);
            Goods goods1 = sqlSession.selectOne("goods.selectById",1603);
            System.out.println(goods.hashCode()+":"+goods1.hashCode());
        }catch (Exception e){
            if(sqlSession!=null){
                sqlSession.rollback();
            }
            throw e;
        }finally {
            MyBatisUtils.closeSession(sqlSession);
        }
    }
复制代码

如下图,goods和goods1指向同一个对象

 

 在两个SqlSession对象中执行重复查询

复制代码
@Test
    public void testlv1Cache(){
        SqlSession sqlSession=null;
        try{
            sqlSession=MyBatisUtils.openSession();
            Goods goods = sqlSession.selectOne("goods.selectById",1603);
            Goods goods1 = sqlSession.selectOne("goods.selectById",1603);
            System.out.println(goods.hashCode()+":"+goods1.hashCode());
        }catch (Exception e){
            if(sqlSession!=null){
                sqlSession.rollback();
            }
            throw e;
        }finally {
            MyBatisUtils.closeSession(sqlSession);
        }

        try{
            sqlSession=MyBatisUtils.openSession();
            Goods goods = sqlSession.selectOne("goods.selectById",1603);
            Goods goods1 = sqlSession.selectOne("goods.selectById",1603);
            System.out.println(goods.hashCode()+":"+goods1.hashCode());
        }catch (Exception e){
            if(sqlSession!=null){
                sqlSession.rollback();
            }
            throw e;
        }finally {
            MyBatisUtils.closeSession(sqlSession);
        }
    }
复制代码

一级缓存的范围只在SqlSession对象中

 

 二级缓存的开启

 在mapper下增加cache标签

复制代码
<?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="goods">

    <!--开启了二级缓存-->
    <cache eviction="LRU" flushInterval="600000" size="512" readOnly="true"/>
 
    <select id="selectById" parameterType="Integer" resultType="com.MyBatis.entity.Goods">
        select * from t_goods where goods_id = #{value}
    </select>

</mapper>
复制代码

测试代码:

复制代码
@Test
    public void testlv2Cache(){
        SqlSession sqlSession=null;
        try{
            sqlSession=MyBatisUtils.openSession();
            Goods goods = sqlSession.selectOne("goods.selectById",1603);
            System.out.println(goods.hashCode());
        }catch (Exception e){
            if(sqlSession!=null){
                sqlSession.rollback();
            }
            throw e;
        }finally {
            MyBatisUtils.closeSession(sqlSession);
        }

        try{
            sqlSession=MyBatisUtils.openSession();
            Goods goods = sqlSession.selectOne("goods.selectById",1603);
            System.out.println(goods.hashCode());
        }catch (Exception e){
            if(sqlSession!=null){
                sqlSession.rollback();
            }
            throw e;
        }finally {
            MyBatisUtils.closeSession(sqlSession);
        }
    }
复制代码

 

 cache的四个设置项:

1.eviction是缓存的清楚策略,当缓存对象数量达到上限后,自动触发对应算法对缓存对象清除
1.LRU - 最近最久未使用:已出最长时间不被使用的对象。
O1 O2 O3 O4 .. O512
14 99 83 1 893
2.FIFO - 先进先出:按对象进入缓存的顺序移除
3.SOFT - 软引用:移除基于垃圾收集器状态和软引用规则的对象
4.WEAK - 弱引用:更积极的移除基于垃圾收集器状态和弱引用规则的对象

2.flushInterval 代表间隔多长时间自动清空缓存,单位毫秒 600000ms=10min

3.size 缓存储存上限,用于保存对象或集合(一个集合算一个对象)的数量上限

4.readOnly 设置为true,代表返回只读缓存,每次从缓存取出的是缓存对象本身,执行效率更高
设置为false,代表每次取出的是缓存 ‘副本’ ,每一次取出的对象是不同的,安全性较高

List在放入缓存时会被当做一个对象,对内存的使用非常大,因此可以在<select>标签中添加属性 useCache="false" 表示不被缓存。在<select>标签中添加属性flushCache="true" 表示在sql执行后强制清空缓存

posted @   南风知君  阅读(465)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示