• MyBaties一级缓存


    一、一级缓存简介

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

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

    用一张图来解释一级缓存,如下图:

    722d730ba50898cb34d01bd8ff1a60694c5.jpg

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

    二、一级缓存配置

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

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

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

    三、一级缓存测试

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

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

    4eb844f98cf523594d86025f85c9bc30e7b.jpg

    我们可以看到,只有第一次真正查询了数据库,后续的查询使用了一级缓存

    测试二、
    在这次的试验中,我们增加了对数据库的修改操作,验证在一次数据库会话中,对数据库发生了修改操作,一级缓存是否会失效

    	@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);
        }

    7bbd1d9528cb967125094b9f5e727afcd62.jpg

    我们可以看到,在修改操作后执行的相同查询,查询了数据库,一级缓存失效。分析:如果是insert/delete/update方法,缓存就会刷新

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

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

    转载于:https://my.oschina.net/u/3387320/blog/2986466

  • 相关阅读:
    springboot 搭建druid数据监控
    spring-boot编写简易mvc
    解决rabbitmq 开启启动报错
    intelij idea 使用maven打包报错 Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1
    php foreach循环引用的问题
    手把手编写hyperf JsonRpc demo
    centos8配置nfs教程本机系统mac
    Java基础的练习题
    Java——循环
    Java——数组
  • 原文地址:https://www.cnblogs.com/twodog/p/12135467.html
Copyright © 2020-2023  润新知