2020-08-07

先说缓存,合理使用缓存是优化中最常见的,将从数据库中查询出来的数据放入缓存中,下次使用时不必从数据库查询,而是直接从缓存中读取,避免频繁操作数据库,减轻数据库的压力,同时提高系统性能。

一级缓存

一级缓存是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查询到数据将存在相同的二级缓存区域中。

开启二级缓存:

1,打开总开关

在MyBatis的配置文件中加入:

[html] view plain copy 

  1. <span style="font-size:18px;"><settings>
  2. <!--开启二级缓存-->
  3. <setting name="cacheEnabled" value="true"/>
  4. </settings> </span>

 

2,在需要开启二级缓存的mapper.xml中加入caceh标签

[html] view plain copy 

  1. <span style="font-size:18px;"><cache/></span>

 

3,让使用二级缓存的POJO类实现Serializable接口

[java] view plain copy 

  1. <span style="font-size:18px;">public class User implements Serializable {}</span>

 

测试一下

[java] view plain copy 

  1. <span style="font-size:18px;">@Test
  2. public void testCache2() throws Exception {
  3. SqlSession sqlSession1 = sqlSessionFactory.openSession();
  4. SqlSession sqlSession2 = sqlSessionFactory.openSession();
  5. UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
  6. User user1 = userMapper1.findUserById(1);
  7. System.out.println(user1);
  8. sqlSession1.close();
  9. UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
  10. User user2 = userMapper2.findUserById(1);
  11. System.out.println(user2);
  12. sqlSession2.close();
  13. }</span>

 

输出结果:

[html] view plain copy 

  1. <span style="font-size:18px;">DEBUG [main] - Cache Hit Ratio [com.iot.mybatis.mapper.UserMapper]: 0.0
  2. DEBUG [main] - Opening JDBC Connection
  3. DEBUG [main] - Created connection 103887628.
  4. DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@631330c]
  5. DEBUG [main] - ==> Preparing: SELECT * FROM user WHERE id=?
  6. DEBUG [main] - ==> Parameters: 1(Integer)
  7. DEBUG [main] - <== Total: 1
  8. User [id=1, username=张三, sex=1, birthday=null, address=null]
  9. DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@631330c]
  10. DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@631330c]
  11. DEBUG [main] - Returned connection 103887628 to pool.
  12. DEBUG [main] - Cache Hit Ratio [com.iot.mybatis.mapper.UserMapper]: 0.5
  13. User [id=1, username=张三, sex=1, birthday=null, address=null]</span>

 

我们可以从打印的信息看出,两个sqlSession,去查询同一条数据,只发起一次select查询语句,第二次直接从Cache中读取。

前面我们说到,Spring和MyBatis整合时, 每次查询之后都要进行关闭sqlSession,关闭之后数据被清空。所以spring整合之后,如果没有事务,一级缓存是没有意义的。那么如果开启二级缓存,关闭sqlsession后,会把该sqlsession一级缓存中的数据添加到namespace的二级缓存中。这样,缓存在sqlsession关闭之后依然存在。

总结:

对于查询多commit少且用户对查询结果实时性要求不高,此时采用mybatis二级缓存技术降低数据库访问量,提高访问速度。

但不能滥用二级缓存,二级缓存也有很多弊端,从MyBatis默认二级缓存是关闭的就可以看出来。

二级缓存是建立在同一个namespace下的,如果对表的操作查询可能有多个namespace,那么得到的数据就是错误的。

举个简单的例子:

订单和订单详情,orderMapper、orderDetailMapper。在查询订单详情时我们需要把订单信息也查询出来,那么这个订单详情的信息被二级缓存在orderDetailMapper的namespace中,这个时候有人要修改订单的基本信息,那就是在orderMapper的namespace下修改,他是不会影响到orderDetailMapper的缓存的,那么你再次查找订单详情时,拿到的是缓存的数据,这个数据其实已经是过时的。

根据以上,想要使用二级缓存时需要想好两个问题:

1)对该表的操作与查询都在同一个namespace下,其他的namespace如果有操作,就会发生数据的脏读。

2)对关联表的查询,关联的所有表的操作都必须在同一个namespace。

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值