MyBatis中的二级缓存和一级缓存介绍版权声明
原创首先是缓存,合理使用缓存是优化中最常见的。从数据库查询的数据被放入高速缓存中。下次使用时,不必从数据库中查询,而是直接从缓存中读取,避免频繁操作数据库,减轻数据库压力,提高系统性能。
一级缓存
一级缓存是SqlSession缓存级别。在操作数据库时,有必要进行构造。sqlSession对象,其中有一个用于存储缓存数据的数据结构。不同sqlSession它们之间的缓存数据区域不会相互影响。也就是说,他只能按照同样的方式行事sqlSession在,不同sqlSession中的缓存不能相互读取。
一级缓存的工作原理:
用户发起查询请求查找一条数据,sqlSession首先在缓存中查找,是否有数据,如果有,则读取;
如果没有,则从数据库中进行查询,并将查询到的数据放入一级缓存区中,以供下一次查找。
但sqlSession执行commit即在添加、删除和修改操作过程中清除缓存。这样做的目的是为了避免肮脏的阅读。
如果commit在不清空缓存的情况下,将出现以下情况:A已查询某商品的库存。10件,并将10库存数据存储在缓存中,然后由客户购买。10数据是delete但是,下次查询此项目时,将出现错误,错误不是来自数据库,而是来自缓存。
既然有一级缓存,为什么要提供二级缓存呢?
二级高速缓存是mapper高速缓存级别,多个SqlSession以同样的方式操作Mapper的sql语句,多个SqlSession可以共用二级缓存,二级高速缓存是跨SqlSession的。二级缓存的作用范围更大。
还有一个原因是,在实际的发展中,MyBatis通常和Spring融合发展。Spring将交易放入Service管理,每个人service中的sqlsession是不同的,这就完成了mybatis-spring中的org.mybatis.spring.mapper.MapperScannerConfigurer创建sqlsession自动注入到service中的。 在每次查询后关闭sqlSession关闭后,数据将被清除。所以spring合并后,如果没有事务,一级缓存就没有意义了。
二级缓存
二级缓存的原理:
二级高速缓存是mapper高速缓存级别,多个SqlSession以同样的方式操作Mapper的sql语句,多个SqlSession可以共用二级缓存,二级高速缓存是跨SqlSession的。
UserMapper有一个辅助缓存区(按namespace积分)、其他mapper还有自己的二级缓存区(按下namespace点)。每个namespace的mapper两者都有一个二级缓存区,两个mapper的namespace如果相同,则两者mapper执行sql查询数据将存在于相同的二级缓存区中。
启用2级缓存:
1,打开主开关
在MyBatis添加到配置文件:
2,在需要打开二级缓存的mapper.xml中加入caceh标签
3,让我们使用二级缓存。POJO类实现Serializable接口
public class User implements Serializable {}
测试一下
@Test
public void testCache2() throws Exception {
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = userMapper1.findUserById(1);
System.out.println(user1);
sqlSession1.close();
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = userMapper2.findUserById(1);
System.out.println(user2);
sqlSession2.close();
}
输出结果:
DEBUG [main] - Cache Hit Ratio [com.iot.mybatis.mapper.UserMapper]: 0.0
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 103887628.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@631330c]
DEBUG [main] - ==> Preparing: SELECT * FROM user WHERE id=?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 1
User [id=1, username=张三, sex=1, birthday=null, address=null]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@631330c]
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@631330c]
DEBUG [main] - Returned connection 103887628 to pool.
DEBUG [main] - Cache Hit Ratio [com.iot.mybatis.mapper.UserMapper]: 0.5
User [id=1, username=张三, sex=1, birthday=null, address=null]
我们从印制的信息中可以看出,两人sqlSession,来查询相同的数据,只查询一次select查询语句,第二个直接从Cache中读取。
就像我们之前说的,Spring和MyBatis整合时, 在每次查询后关闭sqlSession关闭后,数据将被清除。所以spring合并后,如果没有事务,一级缓存就没有意义了。那么如果打开二级缓存,关闭sqlsession在那之后,sqlsession添加一级缓存中的数据。namespace在二级高速缓存中。这样,缓存就进入了。sqlsession它在关闭后仍然存在。
总结:
有关更多查询commit而用户对查询结果的实时性要求不高,此时使用。mybatis二级缓存技术减少了数据库访问,提高了访问速度。
但不能滥用二级缓存,二级缓存也有很多缺点,从。MyBatis默认二级高速缓存是关闭的就可以看出来。
二级高速缓存是建立在同一个namespace在下,如果表上可能有多个操作查询namespace,则结果数据是错误的。
一个简单的例子:
订单和订单详细信息,orderMapper、orderDetailMapper。在查询订单明细时,我们还需要查询订单信息,因此订单明细被缓存在2级。orderDetailMapper的namespace此时,有人想要修改订单的基本信息,即在orderMapper的namespace他不会影响修改。orderDetailMapper然后,当您再次查找订单详细信息时,您会得到缓存的数据,而这些数据实际上已过时。
如上所述,使用二级缓存时需要考虑两个问题:
1对表的操作与查询相同。namespace在下面,其他namespace如果有操作,将会发生脏数据读取。
2)查询关联表,则所有关联表必须在相同的namespace。
————————————————
版权声明:本文是CSDN博主「Java知音_“原文,跟上。 CC 4.0 BY-SA 版权协议,转载请附上原始来源链接和本声明。
原始链接:https://blog.csdn.net/weixin\_36380516/article/details/73194758
版权声明
所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除