mybatis缓存以及插件开发

一、Mybatis缓存

1. 一级缓存
1)概念
	(1)Mybatis的一级缓存是指Session缓存。一级缓存的作用域默认是一个SqlSession
	(2)Mybatis默认开启一级缓存
	(3)也就是在同一个SqlSession中,执行相同的查询SQL,第一次会去数据库进行查询,并写到缓存中;第二次以后是直接去缓存中取
	(4)当执行SQL查询中间发生了增删改的操作,MyBatis会把SqlSession的缓存清空
	(5)注意:当Mybatis整合Spring后,直接通过Spring注入Mapper的形式,如果不是在同一个事务中每个Mapper的每次查询操作都对应一个全新的SqlSession实例,这个时候就不会有一级缓存的命中,但是在同一个事务中时共用的是同一个SqlSession。如有需要可以启用二级缓存
2)一级缓存满足条件
	(1)同一个session中
	(2)相同的SQL和参数
2. 二级缓存
1)概念
	(1)mybatis 的二级缓存的作用域是一个mapper的namespace ,同一个namespace中查询sql可以从缓存中命中
	(2)Mybatis需要手动设置启动二级缓存
2)二级缓存开启
	(1)在mybatis的全局配置文件中配置Setting属性,设置名为cacheEnabled的属性值为true即可
		(<setting name="cacheEnabled" value="true" />)
	(2)在具体需要二级缓存的mapeer映射文件中开启二级缓存,值需要在相应的映射文件中添加一个cache标签即可
		 <mapper namespace="com.zpc.mybatis.dao.UserMapper">
			   <cache/>
		 </mapper>   
3)配置效果
	(1)二级缓存存在与Mapper实例中,当多个SqlSession类的实例对象加载相同的mapper文件,并执行其中相同的SQL配置时,他们就共享一个Mapper缓存。当某个SqlSession类的实例对象执行了增,删,改,等改变数据的操作时,Mapper实例都会清空其二级缓存
	(2) 映射语句文件中的所有select语句将会被缓存
	(3)映射语句文件中的所欲insert、update和delete语句会刷新缓存	
	(4)缓存会使用默认的Least Recently Used(LRU,最近最少使用的)算法来收回
	(5)根据时间表,比如No Flush Interval,(CNFI没有刷新间隔),缓存不会以任何时间顺序来刷新
	(6)根据时间表,比如No Flush Interval,(CNFI没有刷新间隔),缓存不会以任何时间顺序来刷新
	(7)缓存会被视为是read/write(可读/可写)的缓存,意味着对象检索不是共享的,而且可以安全的被调用者修改,不干扰其他调用者或线程所做的潜在修改
4)使用原则
	(1)只能在一个命名空间下使用二级缓存
		a. 由于二级缓存中的数据是基于namespace的,即不同namespace中的数据互不干扰。在多个namespace中若均存在对同一个表的操作,那么这多个namespace中的数据可能就会出现不一致现象
	(2)在单表上使用二级缓存	
		a. 如果一个表与其它表有关联关系,那么久非常有可能存在多个namespace对同一数据的操作。而不同namespace中的数据互补干扰,所以就有可能出现多个namespace中的数据不一致现象
	(3)查询多于修改时使用二级缓存	
		a. 在查询操作远远多于增删改操作的情况下可以使用二级缓存。因为任何增删改操作都将刷新二级缓存,对二级缓存的频繁刷新将降低系统性能

二、mybatis插件开发

1. Mybatis插件概念
1)与其称为Mybatis插件,不如叫Mybatis拦截器,更加符合其功能定位,实际上它就是一个拦截器,应用代理模式,在方法级别上进行拦截
2)mybatis插件就是对ParameterHandler、ResultSetHandler、StatementHandler、Executor这四个接口上的方法进行拦截,利用JDK动态代理机制,为这些接口的实现类创建代理对象,在执行方法时,先去执行代理对象的方法,从而执行自己编写的拦截逻辑,所以真正要用好mybatis插件,主要还是要熟悉这四个接口的方法以及这些方法上的参数的含义
2. 支持拦截的方法
1)执行器Executor(update、query、commit、rollback等方法)
2)参数处理器ParameterHandler(getParameterObject、setParameters方法)
3)结果集处理器ResultSetHandler(handleResultSets、handleOutputParameters等方法)
4)SQL语法构建器StatementHandler(prepare、parameterize、batch、update、query等方法)
3. 编写步骤
1)编写Interceptor的实现类(3个方法需要重写)
	(1)Intercept:拦截目标方法执行(要自己写的逻辑)
	(2)plugin:生成动态代理对象,可以使用MyBatis提供的Plugin类的wrap方法
	(3)setProperties:注入插件配置时设置的属性
2)使用@Intercepts注解完成插件签名
	(1)Intercepts 标识我的类是一个拦截器
	(2)Signature 则是指明我们的拦截器需要拦截哪一个接口的哪一个方法
		a. type : 对应四类接口中的某一个,比如是 Executor
		b. method : 对应接口中的哪类方法,比如 Executor 的 update 方法
		c. args 对应接口中的哪一个方法,比如 Executor 中 query 因为重载原因,方法有多个,args 就是指明参数类型,从而确定是哪一个方法
3)将写好的插件注册到全局配置文件中	
	(1)创建动态代理的时候,是按照插件的配置顺序,创建层层代理对象
	(2)执行目标方法的时候,按照逆序执行
4. 典型适用场景
1)分页功能
	(1)mybatis的分页默认是基于内存分页的(查出所有,再截取),数据量大的情况下效率较低,不过使用mybatis插件可以改变该行为,只需要拦截StatementHandler类的prepare方法,改变要执行的SQL语句为分页语句即可
2)公共字段统一赋值
	(1)一般业务系统都会有创建者,创建时间,修改者,修改时间四个字段,对于这四个字段的赋值,实际上可以在DAO层统一拦截处理,可以用mybatis插件拦截Executor类的update方法,对相关参数进行统一赋值即可
3)性能监控
	(1)对于SQL语句执行的性能监控,可以通过拦截Executor类的update, query等方法,用日志记录每个方法执行的时间
4)批量操作
	(1)批量操作我们是使用MyBatis提供的BatchExecutor进行的,他的底层就是通过jdbc攒sql的方式进行的。我们可以让他攒够一定数量后发给数据库一次
5)存储过程
	(1)实际开发中,我们通常也会写一些存储过程,MyBatis也支持对存储过程的调用
6)自定义TypeHandler处理枚举
	(1)我们可以通过自定义TypeHandler的形式来在设置参数或者取出结果集的时候自定义参数封装策略

参考网址

mybatis的缓存机制

mybatis一级缓存二级缓存

Mybatis插件开发–实现sql拦截器-重置sql中的参数

MyBatis插件开发

注:文章是经过参考其他的文章然后自己整理出来的,有可能是小部分参考,也有可能是大部分参考,但绝对不是直接转载,觉得侵权了我会删,我只是把这个用于自己的笔记,顺便整理下知识的同时,能帮到一部分人。
ps : 有错误的还望各位大佬指正,小弟不胜感激

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值