Mybatis缓存简介

1.Mybatis数据库缓存概述

      Mybatis提供查询缓存,用于减轻数据压力,提高数据库性能。Mybatis提供一级缓存和二级缓存。Mybatis提供一级缓存和二级缓存。Mybatis一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率,当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了,Mybatis默认开启一级缓存。Mybatis二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的(sql中传递参数也相同)相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。

2.Mybatis一级缓存

  

  mybatis一级缓存是指在内存中开辟一块区域,用来保存用户对数据库的操作信息(sql)和数据库返回的数据,如果下一次用户再执行相同的请求,那么直接从内存中读数数据而不是从数据库读取。 其中数据的生命周期有两个影响因素。其一是对sqlsession执行commit操作,也就意味着用户执行了update、delete等操作,那么数据库中的数据势必会发生变化,如果用户请求数据仍然使用之前内存中的数据,那么将读到脏数据。所以在执行sqlsession commit操作后,会清除保存数据的HashMap,用户在发起查询请求时就会重新读取数据并放入一级缓存中了。第一次发起查询,先去找缓存中是否有id为1的用户信息,如果没有,从数据库中查询用户信息。得到用户信息,将用户信息存储到一级缓存中。第二次发起查询用户id为1的用户信息,先去缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。如果SqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存。目的是为了让缓存中存储的是最新的信息,避免脏读。Mybatis默认支持一级缓存,不需要在配置文件中配置。Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句,value为从查询出来映射生成的java对象。注意:当MyBatis与spring整合后,如果没有事务,一级缓存是失效的!原因就是两者结合后,sqlsession如果发现当前没有事务,那么每执行一个mapper方法,sqlsession就被关闭了。如果需要维持一级缓存的可用性,有两种途径:一是添加事务;二是使用二级缓存。

3.Mybatis二级缓存

  

  MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能。SqlSession1去查询用户id为1的用户信息,查询到用户信息会将查询数据存储到二级缓存中。SqlSession2去查询用户id为1的用户信息,去缓存中找是否存在数据,如果存在直接从缓存中取出数据。二级缓存区域是根据mapper的namespace划分的,相同namespace的mapper查询数据放在同一个区域,如果使用mapper代理方法每个mapper的namespace都不同,此时可以理解为二级缓存区域是根据mapper划分。每次查询会先从缓存区域找,如果找不到从数据库查询,查询到数据将数据写入缓存。Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象。sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。

4.总结

      对于查询多commit少且用户对查询结果实时性要求不高,此时采用mybatis二级缓存技术降低数据库访问量,提高访问速度。但不能滥用二级缓存,二级缓存也有很多弊端,从MyBatis默认二级缓存是关闭的就可以看出来。二级缓存是建立在同一个namespace下的,如果对表的操作查询可能有多个namespace,那么得到的数据就是错误的。举个简单的例子:订单和订单详情,orderMapper、orderDetailMapper。在查询订单详情时我们需要把订单信息也查询出来,那么这个订单详情的信息被二级缓存在orderDetailMapper的namespace中,这个时候有人要修改订单的基本信息,那就是在orderMapper的namespace下修改,他是不会影响到orderDetailMapper的缓存的,那么你再次查找订单详情时,拿到的是缓存的数据,这个数据其实已经是过时的。根据以上,想要使用二级缓存时需要想好两个问题:

  • 对该表的操作与查询都在同一个namespace下,其他的namespace如果有操作,就会发生数据的脏读。
  • 对关联表的查询,关联的所有表的操作都必须在同一个namespace。
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

抽离的心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值