Mybatis缓存

一级缓存:

先看一个示例:

@Test
public void test (){
      SqlSession sqlSession= sqlSessionFactory.openSession();
      GmGoodsMapper gmGoodsMapper = sqlSession.getMapper(GmGoodsMapper.class);
      System.out.println("==============第一次查询==================");
      System.out.println(gmGoodsMapper.findAllById(1));

      System.out.println("==============第二次查询==================");
      System.out.println(gmGoodsMapper.findAllById(1));
}

在配置文件yml中开启sql日志打印功能:

logging:
  level:
    com.dongsq.datasource.mapper:
      debug

接下来执行测试用例,可以看到:

从打印的结果来看,第二次查询没有打印preparing后面的sql语句,也就是并没有执行这个sql却把结果打印出来了,说明结果已经缓存了。

接下来修改mybatis中的配置,加上flushCache="true":

<select id="findAllById" flushCache="true"  resultType="com.dongsq.datasource.entity.GmGoods">
        select * from gm_goods where id= #{id}
</select>

 再看一下打印的结果:

 这样就两次都执行了sql,没有走缓存。

说明:mybatis一级缓存是默认开启的flushCache="false",关闭一级缓存只需设置flushCache="true"即可,它的意思表示在执行sql之前,清除一级缓存。

修改一下测试代码,修改flushCache="false",然后用两个不同的sqlSession去查询:

@Test
public void test (){
        SqlSession sqlSession1= sqlSessionFactory.openSession();
        GmGoodsMapper gmGoodsMapper1 = sqlSession1.getMapper(GmGoodsMapper.class);
        SqlSession sqlSession2= sqlSessionFactory.openSession();
        GmGoodsMapper gmGoodsMapper2 = sqlSession2.getMapper(GmGoodsMapper.class);
        System.out.println("==============第一次查询==================");
        System.out.println(gmGoodsMapper1.findAllById(1));


        System.out.println("==============第二次查询==================");
        System.out.println(gmGoodsMapper2.findAllById(1));
}

可以看到结果:

 说明:

1、一级缓存只跟sqlSession相关,两个不同的sqlSession不能共享一级缓存。在同一个sqlSession中查询时,Mybatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个Map对象中,如果同一个sqlSession中执行的方法和参数完全一致,那么通过算法会生成相同的键值,当Map缓存对象中已经存在该键值时,则会返回缓存中的对象,任何的INSERT,UPDATE,DELETE操作都会清空一级缓存。

2、一级缓存在分布式的情况下可能存在问题,两个不同的节点,一个查询,一个修改。

---------------------------------------------------------------------------------------------------------------------------------

二级缓存:

        1、二级缓存存在于sqlSessionFactory的生命周期中,可以理解为跨sqlSession,缓存时以namespace为单位的,不同的namespace下操作互不影响。

        2、参数cacheEnabled,这个参数是二级缓存的全局开关,默认值是true,如果把这个设置为false,即使后面的二级缓存配置,也不会生效。

接下来开启二级缓存:

1、yml中配置:

mybatis:
  configuration:
    cache-enabled: true

 2、在mapper文件中配置<cache/>标签,和useCache="true"表示开启二级缓存,如果useCache没有配置,则会根据标签是不是select来判断useCache的值是true还是false。

3、java代码中做以下修改,只有commit操作后,才会将数据刷到二级缓存中。

看下同一个sqlSessionFactory,两个不同的sqlSession的查询结果:

 可以看到,开启二级缓存后会打印命中率(查询了两次,其中一次走的二级缓存,所以命中率是0.5),第一次没有走缓存,执行的sql,第二次没有打印sql,直接在二级缓存中取得数据。

最后强调一点:二级缓存慎用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值