• 看了他,妈妈再也不用担心我被问到Mybatis缓存了


    Mybatis缓存

    一、一级缓存
    1. 概念
    • sqlsession级别的缓存,即缓存的是SQL语句
    • 同一个sqlsession中执行多次查询条件相同的SQL,mybatis会提供一级缓存进行优化
    2. 开启和关闭
    • 开启

      • 默认开启
    • 关闭

      <setting name="localCacheScope" value="STATEMENT"/>

    3. 使用
    @Test
        public void method() throws IOException {
            // 1.读取核心配置文件
            InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    
            // 2.获取sqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
    
    
            // 3.获取sqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            // 4.获取mapper
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    
            // 5.调用相应的方法
            Student student = mapper.getStudentById(1);
            System.out.println(student);
    
    
    
            System.out.println("----------------------------");
    
            // 同一个sqlsession中执行相同的SQL查询,会走一级缓存
            Student student1 = mapper.getStudentById(1);
            System.out.println(student1);
    
    
    
            // 6.释放资源
            sqlSession.close();
            in.close();
        }
    
    4. 什么时候失效
    • 通过同一个SqlSession执行更新操作时,这个更新操作不仅仅指代update操作,还指插入和删除操作;
    • 事务提交时会删除一级缓存;
    • 事务回滚时也会删除一级缓存
    5. 使用建议
    平时使用MyBatis时都是和Spring结合使用的,在整个Spring容器中一般只有一个SqlSession实现类(bean默认是单例的)。而Spring一般都是主动提交事务的,所以说一级缓存经常失效。
    
    还有就是我们也很少在一个事务范围内执行同一个SQL两遍,上面的这些原因导致我们在开发过程中很少注意到MyBatis一级缓存的存在。
    
    不怎么用并不是说不用,作为一个合格的开发者需要对这些心知肚明,要清楚的知道MyBatis一级缓存的工作流程。
    
    
    二、二级缓存
    1. 概念
    • mapper级别的缓存
    2. 开启
    • 核心配置文件:mybtis-config.xml

       <setting name="cacheEnabled" value="true"/>
      
    • mapper

      @CacheNamespace(blocking = true)
      
    3. 使用

    /**
         * 二级缓存:
         *  1.同一个sqlsession中,相同的SQL查询,会走缓存
         *  2.中途执行了更新,则下次的SQL查询不走缓存
         *  3.前面的sqlsession关闭之后,后面的sqlsession如果执行的是相同的SQL,则会走缓存
         *
         * @throws IOException
         */
        @Test
        public void method2() throws IOException {
            // 1.读取核心配置文件
            InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    
            // 2.获取sqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
    
    
            // 3.获取sqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            // 4.获取mapper
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    
            // 5.调用相应的方法
            Student student = mapper.getStudentById(1);
            System.out.println(student);
    
    
            System.out.println("----------------------------");
    
            // 执行更新操作:查看下面的查询是否还会走缓存
    //        int num = mapper.updateById(1);
    //        System.out.println(" num = "+num);
    //
    //        System.out.println("----------------------------");
    
            sqlSession.close();
    
            // 同一个sqlsession中执行相同的SQL查询,会走一级缓存
            SqlSession sqlSession1 = sqlSessionFactory.openSession();
    
            // 4.获取mapper
            StudentMapper mapper1 = sqlSession1.getMapper(StudentMapper.class);
            Student student1 = mapper1.getStudentById(1);
            System.out.println(student1);
    
    
    
            // 6.释放资源
            sqlSession1.close();
    //        sqlSession.close();
            in.close();
        }
    
    4. 什么时候失效
    • 二级缓存是以namespace(Mapper)为单位的,不同namespace下的操作互不影响。
    • insert,update,delete操作会清空所在namespace下的全部缓存。
    • 多表操作一定不要使用二级缓存,因为多表操作进行更新操作,一定会产生脏数据。
    5. 使用建议
    MyBatis的二级缓存实用性不是很大。一个原因就是Spring环境下,一本只有一个SqlSession,不存在sqlSession之间共享缓存;还有就是
    MyBatis的缓存都不能做到分布式,所以对于MyBatis的二级缓存以了解为主。
    
    总结
    1. 一级缓存
    一级缓存的本质是Executor的一个类似Map的属性;
    一级缓存默认开启,将flushCache设置成true或者将全局配置localCacheScope设置成Statement可以关闭一级缓存;
    在一级缓存开启的情况下,查询操作会先查询一级缓存,再查询数据库;
    增删改操作和事务提交回滚操作会导致一级缓存失效;
    由于Spring中事务是自动提交的,因此Spring下的MyBatis一级缓存经常失效。(但是并不表示不生效,除非你手动关闭一级缓存)
    不能实现分布式。
    
    
    2. 二级缓存
    namesapce级别的缓存(Mapper级别或者叫做表级别的缓存),设计的主要目的是实现sqlSession之间的缓存共享;
    开启二级缓存后,查询的逻辑是二级缓存->一级缓存->数据库;
    insert,update,delete操作会清空所在namespace下的全部缓存;
    多表查询一定不要使用二级缓存,因为多表操作进行更新操作,可能会产生脏数据。
    总体来说,MyBatis的缓存功能比较鸡肋。想要使用缓存的话还是建议使用spring-cache等框架。
    
    
  • 相关阅读:
    MD5 Hashing in Java
    Caching in Presto
    ORC 文件存储格式
    Presto 性能优化点
    数据分页问题
    ES
    ES
    ES
    ES
    ES
  • 原文地址:https://www.cnblogs.com/pretttyboy/p/13288787.html
Copyright © 2020-2023  润新知