博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mybatis缓存以及插件开发
阅读量:4142 次
发布时间:2019-05-25

本文共 3126 字,大约阅读时间需要 10 分钟。

一、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即可		(
) (2)在具体需要二级缓存的mapeer映射文件中开启二级缓存,值需要在相应的映射文件中添加一个cache标签即可
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的形式来在设置参数或者取出结果集的时候自定义参数封装策略

参考网址

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

ps : 有错误的还望各位大佬指正,小弟不胜感激

你可能感兴趣的文章
andorid里关于wifi的分析
查看>>
Spring MVC和Struts2的比较
查看>>
Hibernate和IBatis对比
查看>>
Spring MVC 教程,快速入门,深入分析
查看>>
Android 的source (需安装 git repo)
查看>>
Commit our mod to our own repo server
查看>>
LOCAL_PRELINK_MODULE和prelink-linux-arm.map
查看>>
Simple Guide to use the gdb tool in Android environment
查看>>
Netconsole to capture the log
查看>>
Build GingerBread on 32 bit machine.
查看>>
How to make SD Card world wide writable
查看>>
Detecting Memory Leaks in Kernel
查看>>
Linux initial RAM disk (initrd) overview
查看>>
Timestamping Linux kernel printk output in dmesg for fun and profit
查看>>
There's Much More than Intel/AMD Inside
查看>>
apache和tomcat整合
查看>>
java虚拟机错误问题
查看>>
oracle建立表空间
查看>>
oracle分区表的性能提升
查看>>
"Cannot allocate memory" OutofMemory when call Ant to build Polish project in Tomcat
查看>>