zoukankan      html  css  js  c++  java
  • MyBatis框架一级缓存与二级缓存

    为了提升查询效率,提高用户体验,MyBatis提供了数据缓存支持,依据数据缓存的有效范围默认定义了一级缓存和二级缓存

    一级缓存

    1、该级缓存默认开启,不能关闭;

    2、该级缓存为SqlSession级别的缓存,也称为本地缓存;

    3、以下4种情况将会导致该级缓存失效:

      a、在不同SqlSession中查询数据;

    public class Test {
    
        public static void main(String[] args) {
            try {
                InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
                SqlSession sqlSession = sqlSessionFactory.openSession(true);//为true自动提交,默认false开启事务需要手动commit
                
                IUserInfoDao userInfoDao = sqlSession.getMapper(IUserInfoDao.class);
                List<UserInfo>list = userInfoDao.select();
                System.out.println(list.size());
                list = userInfoDao.select();
                System.out.println(list.size());
                sqlSession.close();
                
                sqlSession = sqlSessionFactory.openSession();
                userInfoDao = sqlSession.getMapper(IUserInfoDao.class);
                list = userInfoDao.select();
                System.out.println(list.size());
                sqlSession.close();
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    }

    执行结果:同一个sqlSession中缓存成功,不同的sqlSession缓存失效

      b、相同SqlSession中查询数据,但查询条件不同

    public class Test {
    
        public static void main(String[] args) {
            try {
                InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
                SqlSession sqlSession = sqlSessionFactory.openSession(true);//为true自动提交,默认false开启事务需要手动commit
                
                IUserInfoDao userInfoDao = sqlSession.getMapper(IUserInfoDao.class);
                List<UserInfo>list = userInfoDao.select("%阿%");
                System.out.println(list.size());
                list = userInfoDao.select("%a%");
                System.out.println(list.size());
                sqlSession.close();
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    }

    执行结果:

      c、相同SqlSession中查询数据,但两次查询之间执行了增删改操作

    public class Test {
    
        public static void main(String[] args) {
            try {
                InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
                SqlSession sqlSession = sqlSessionFactory.openSession(true);//为true自动提交,默认false开启事务需要手动commit
                
                IUserInfoDao userInfoDao = sqlSession.getMapper(IUserInfoDao.class);
                List<UserInfo>list = userInfoDao.select();
                System.out.println(list.size());
                
                boolean flag = userInfoDao.delete("1");
                System.out.println(flag);
                
                list = userInfoDao.select();
                System.out.println(list.size());
    
                sqlSession.close();
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    }

    执行结果:

      d、相同SqlSession中查询数据,但第二次查询前,程序调用SqlSession对象clearCache()方法手动清除了一级缓存

    public class Test {
    
        public static void main(String[] args) {
            try {
                InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
                SqlSession sqlSession = sqlSessionFactory.openSession(true);//为true自动提交,默认false开启事务需要手动commit
                
                IUserInfoDao userInfoDao = sqlSession.getMapper(IUserInfoDao.class);
                List<UserInfo>list = userInfoDao.select();
                System.out.println(list.size());
                
                sqlSession.clearCache();
                
                list = userInfoDao.select();
                System.out.println(list.size());
    
                sqlSession.close();
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    }

    执行结果:

    二级缓存

    1、该级缓默认不开启,但如果使用二级缓存需要在每个XML映射文件中添加<cache></cache>以配置该级缓存(相应实体类要序列化)。二级缓存可以通过在全局配置文件配置setting标签来关闭该级缓存。

    ​ 如果这样配置的话,很多其他的配置就会被默认进行,如:

    • 映射文件所有的select 语句会被缓存
    • 映射文件的所有的insert、update和delete语句会刷新缓存
    • 缓存会使用默认的Least Recently Used(LRU,最近最少使用原则)的算法来回收缓存空间
    • 根据时间表,比如No Flush Interval,(CNFI,没有刷新间隔),缓存不会以任何时间顺序来刷新
    • 缓存会存储列表集合或对象(无论查询方法返回什么)的1024个引用
    • 缓存会被视为是read/write(可读/可写)的缓存,意味着对象检索不是共享的,而且可以很安全的被调用者修改,不干扰其他调用者或县城所作的潜在修改

    可以在开启二级缓存时候,手动配置一些属性

    <cache eviction="LRU" flushInterval="100000" size="1024" readOnly="true"/>

    各个属性意义如下:

    • eviction:缓存回收策略
      - LRU:最少使用原则,移除最长时间不使用的对象
      - FIFO:先进先出原则,按照对象进入缓存顺序进行回收
      - SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象
      - WEAK:弱引用,更积极的移除移除基于垃圾回收器状态和弱引用规则的对象
    • flushInterval:刷新时间间隔,单位为毫秒,这里配置的100毫秒。如果不配置,那么只有在进行数据库修改操作才会被动刷新缓存区
    • size:引用额数目,代表缓存最多可以存储的对象个数
    • readOnly:是否只读,如果为true,则所有相同的sql语句返回的是同一个对象(有助于提高性能,但并发操作同一条数据时,可能不安全),如果设置为false,则相同的sql,后面访问的是cache的clone副本。

    2、该级缓存为namespace级别的缓存

    3、工作机制:通过SqlSession查询数据,这些数据将会放到当前会话的一级缓存中;如果当前会关闭,则一级缓存中的数据会被保存到二级缓存中,此后新的SqlSession将从二级缓存中查找数据;

    public class Test {
    
        public static void main(String[] args) {
            try {
                InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
                SqlSession sqlSession = sqlSessionFactory.openSession(true);//为true自动提交,默认false开启事务需要手动commit
                
                IUserInfoDao userInfoDao = sqlSession.getMapper(IUserInfoDao.class);
                List<UserInfo>list = userInfoDao.select();
                System.out.println(list.size());
                
                sqlSession.close();
                
                sqlSession = sqlSessionFactory.openSession();
                userInfoDao = sqlSession.getMapper(IUserInfoDao.class);
                list = userInfoDao.select();
                System.out.println(list.size());
                sqlSession.close();
    
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    }

    执行结果:

    4select标签的useCache属性用于设置是否使用二级缓存;insertupdatedeleteselect标签均有flushCache属性,其中增删改默认true,即sql执行以后,会同时清空一级和二级缓存,查询默认false

    public class Test {
    
        public static void main(String[] args) {
            try {
                InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
                SqlSession sqlSession = sqlSessionFactory.openSession(true);//为true自动提交,默认false开启事务需要手动commit
                
                IUserInfoDao userInfoDao = sqlSession.getMapper(IUserInfoDao.class);
                List<UserInfo>list = userInfoDao.select();
                System.out.println(list.size());
                
                sqlSession.close();
                        
                sqlSession = sqlSessionFactory.openSession();
                userInfoDao = sqlSession.getMapper(IUserInfoDao.class);
                boolean flag = userInfoDao.delete("1");//清空二级缓存
                System.out.println(flag);
                
                list = userInfoDao.select();
                System.out.println(list.size());
                sqlSession.close();
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    }

    执行结果:

     

    5、为了提高扩展性,MyBatis定义了Cache缓存接口,可以通过实现该缓存接口自定义二级缓存,jar包下载:https://github.com/mybatis

    为了提升查询效率,提高用户体验,MyBatis提供了数据缓存支持,依据数据缓存的有效范围默认定义了一级缓存和二级缓存

  • 相关阅读:
    ajax 中文乱码问题 主要是IE浏览器
    js 带省略号的分页源码及应用实例
    js iframe onload &line-height浏览器兼容问题
    Js 正则表达式特殊字符含义
    js prototype
    js call apply caller callee bind
    怎么查看一个网站是用什么语言编写的?
    ASP.NET之AreaRegistration
    产品经理
    程序猿全面充电10本书
  • 原文地址:https://www.cnblogs.com/yimengxianzhi/p/12395218.html
Copyright © 2011-2022 走看看