Mybatis缓存机制介绍


1.分类

一级缓存(sqlSession级别),二级缓存(sqlSessionFactory级别),第三方缓存。

2.一级缓存

同一个sqlSession它能将查询过的数据存放在缓存区内,当我们再次查询时不需要从数据库中重新查询,而是直接获取缓存区内的数据这样做对于需要反复查询一些相同的数据来说可以大大节省查询时间,提高查询效率。

注意事项:
它只能缓存由同一个sqlSession创建出的mapper代理实现类对象查询的结果,这里面的mapper代理实现类对象不唯一。但要求它们必须是由同一个sqlSession对象产生;
它只能缓存已查询的数据,对于未查询的数据无法实现缓存功能;
对于某张表中任意一条数据进行增删改操作都会导致缓存区自动清除该表相关的缓存数据(否则会引起数据不一致性);
我们手动清除缓存区的数据同样会导致无法获取缓存区数据;

代码演示:

try {
            InputStream is= Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory=sqlSessionFactoryBuilder.build(is);
            SqlSession sqlSession=sqlSessionFactory.openSession();
            EmpMapper emp=sqlSession.getMapper(EmpMapper.class);
            //可以看出不管是同一个mapper对象还是多个mapper对象在查询时都是从缓存区中获取的数据
            System.out.println(emp.selectEmpName(1));
            System.out.println(emp.selectEmpName(1));
            //此时因为对缓存区中数据进行了手动清除,因此我们再次查询时还是会从数据库中查询数据
            sqlSession.clearCache();
            EmpMapper emp1=sqlSession.getMapper(EmpMapper.class);
            System.out.println(emp1.selectEmpName(1));
     }catch (IOException e) {
            e.printStackTrace();
     }

3.二级缓存

由同一个sqlSessionFactory对象创建的一个或者多个sqlSession对象它们查询的结果统一存放在二级缓存中从而实现内部数据可共享。

注意事项:
同一个sqlSessionFactory对象,要求我们在实现数据共享时要确保它的sqlSession对象已处于断开或者提交状态;
对于我们的实体类对象要求继承Serializable接口;
我们需要在映射文件中设置cache标签;
表中任意一条数据发生增删改操作都会导致该表相关的缓存数据自动清除;

代码演示:

try {
           InputStream is= Resources.getResourceAsStream("mybatis-config.xml");
           SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder();
           SqlSessionFactory sqlSessionFactory=sqlSessionFactoryBuilder.build(is);
           SqlSession sqlSession=sqlSessionFactory.openSession();       
//         创建多个sqlSession对象查询信息当完成提交/关闭操作时,
//         此时一级缓存上升至二级缓存从而sqlSession对象内部可以实现资源
//         共享
            SqlSession sqlSession1=sqlSessionFactory.openSession();
            EmpMapper emp2=sqlSession1.getMapper(EmpMapper.class);
            System.out.println(emp2.selectEmpName(2));
            sqlSession1.commit();
            sqlSession1.close();
            SqlSession sqlSession2=sqlSessionFactory.openSession();
            EmpMapper emp3=sqlSession2.getMapper(EmpMapper.class);
            System.out.println(emp3.selectEmpName(2));
            sqlSession2.commit();
            sqlSession2.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

3.第三方缓存

为提高二级缓存的扩展性,可以通过Cache接口定义二级缓存.

4.Mybatis的缓存机制

它既然可以存储我们查询出来的数据,它就需要占据一定的空间。如何设置空间的大小就成为影响它缓存能力的一个重要因素这里就对应是它的Size属性,不过一般我们并不需要特别设置,系统有它的默认大小。
当存储的数据已经超过实际能存储最大的数据量时如何舍弃里面一部分的数据就需要进行考虑于是就有了eviction属性它有一些策略能有效解决此问题。这里提及几个主要的策略:FIFO策略:先进先出策略会最先摒弃占用缓存区时间最长的数据,LRU策略:对于缓存区内被查询次数较少的缓存数据会被摒弃。
ReadOnly属性:值为true时(表示只读)对于我们查询的数据缓存在缓存区内部并不再发生更改,再次查询该数据时返回缓存区中的数据。
值为false时(表示允许读写)将查询的数据作为一个模板存放在缓存区内部并同时进行备份,每当我们再查询时若对该数据进行修改(修改的是备份数据,模板数据不会改变)然后模板数据又会再次备份。

5. 二级缓存与一级缓存之间的关系

当我们查询数据时mybatis会先访问当前sqlSessionFactory对象的缓存区(即二级缓存),若未找到则逐个访问由它创建的sqlSession对象内的缓存区(对应就是一级缓存)因为存在sqlSession是否提交/关闭会使得一级缓存无法上升到二级缓存。如果此时sqlSession的缓存区没有该数据,mybatis只能从数据库中查询数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值