MyBaties一级缓存

1、一级缓存简介

在系统代码的运行中,咱们可能会在一个数据库会话中,执行屡次查询条件彻底相同的Sql,鉴于平常应用的大部分场景都是读多写少,这重复的查询会带来必定的网络开销,同时select查询的量比较大的话,对数据库的性能是有比较大的影响的。Mybatis提供了一级缓存的方案来优化在数据库会话间重复查询的问题。实现的方式是每个SqlSession中都持有了本身的缓存:spring

一种是SESSION级别,即在一个Mybatis会话中执行的全部语句,都会共享这一个缓存
一种是STATEMENT级别,能够理解为缓存只对当前执行的这一个statement有效sql

用一张图来解释一级缓存,以下图:数据库

 

每个SqlSession中持有了本身的Executor,每个Executor中有一个Local Cache。当用户发起查询时,Mybatis会根据当前执行的MappedStatement生成一个key,去Local Cache中查询,若是缓存命中的话,返回。若是缓存没有命中的话,则写入Local Cache,最后返回结果给用户。
 缓存

2、一级缓存配置

只须要在Mybatis的配置文件中,添加以下语句,就可使用一级缓存。共有两个选项,SESSION或者STATEMENT,默认是SESSION级别
<setting name="localCacheScope" value="SESSION"/>网络

注意:spring结合mybatis时一级缓存失效问题
一、在未开启事物的状况之下,每次查询,spring都会关闭旧的sqlSession而建立新的sqlSession,所以此时的一级缓存是没有启做用的mybatis

二、在开启事物的状况之下,spring使用threadLocal获取当前资源绑定同一个sqlSession,所以此时一级缓存是有效的app

3、一级缓存测试

    测试1、
    开启一级缓存,范围为会话级别,调用两次selectByPrimaryKey分布式

@Transactional
    public void test4() {
        
        User user=userMapper.selectByPrimaryKey(1);
        System.out.println(user);
        User user2=userMapper.selectByPrimaryKey(1);
        System.out.println(user2);
       
    }

咱们能够看到,只有第一次真正查询了数据库,后续的查询使用了一级缓存性能

 

测试2、
在此次的试验中,咱们增长了对数据库的修改操做,验证在一次数据库会话中,对数据库发生了修改操做,一级缓存是否会失效测试

@Transactional
    public void test4() {
        User user=userMapper.selectByPrimaryKey(1);
        System.out.println(user);
        User user3=new User();
        user3.setUsername("123");
        userMapper.insert(user3);
        User user2=userMapper.selectByPrimaryKey(1);
        System.out.println(user2);
    }

咱们能够看到,在修改操做后执行的相同查询,查询了数据库,一级缓存失效。分析:若是是insert/delete/update方法,缓存就会刷新

一级缓存总结:
一、Mybatis一级缓存的生命周期和SqlSession一致。
二、Mybatis的缓存是一个粗粒度的缓存,没有更新缓存和缓存过时的概念,同时只是使用了默认的hashmap,也没有作容量上的限定。
三、Mybatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,有操做数据库写的话,会引发脏数据,建议是把一级缓存的默认级别设定为Statement,即不使用一级缓存。
 

文章参考:https://www.jianshu.com/p/c553169c5921

相关文章
相关标签/搜索