(四)mybatis缓存、事务、插件的基本知识
mybatis缓存、事务、插件的基础
一、缓存
(一)一级缓存与二级缓存
一级缓存
为了获得更好的性能,最重要的就是一级缓存。每个session对象维持一个一级缓存,session对象创建时缓存创建,session对象释放时缓存销毁。
缓存是一个哈希表。哈希表根据唯一键存储值,值可以根据唯一键检索。一个实体由它的ID唯一标识,如果两个实体类型相同,ID也相等,那么这两个实体是相等的。
session对象从数据库中加载指定ID的实体,然后放到一级缓存中,访问该实体的键是它的ID值。当系统再次从数据库中加载同一个实体时,session对象首先检查它的缓存,如果实体已经存在于缓存中,就返回缓存的实例。只有实体不在缓存时,session对象才从数据库中加载实体。
二级缓存
一级缓存绑定到session对象,也就是说每次session被释放,所有的缓存数据就会丢失。
二级缓存定义在session工厂级别的,只要session工厂没有被释放缓存就一直存在。一旦实体加载,二级缓存就被激活,实体对所有的session(同session工厂的)都可用。这样,只要实体在二级缓存中,对象就不会从数据库加载实体,直到它从缓存中移除。
(二)mybatis缓存
mybatis默认开启一级缓存,即一个缓存相对于同一个SqlSession而言。使用同一个session查询时,mybatis会将其放在缓存中,以后再查询时,如果没有声明需要刷新,在缓存未超时的情况下,SQLSession都只会取出当前缓存数据。若使用不同的SQLSession对象,调用相同的mapper、参数和方法,均需要到数据库执行。
二级缓存的开启需要配置,并且要求返回的POJO是可序列化的,即实体类实现Serializable接口;在映射XML文件配置<cache/>就可以开启缓存了。
详细配置:<cache eviction="LRU" flushInterval="100000" size="1024" readOnly="true"/>
eviction:缓存回收策略
1.LRU,最近最少使用的,移除最长时间不用的对象
2.FIFO,先进先出,按对象进入缓存的顺序来移除
3.SOFT,软引用,移除基于垃圾回收器状态和软引用规则的对象
4.WEAK,弱引用,更积极地移除基于垃圾收集器状态和弱引用规则的对象。
flushInterval:刷新时间间隔,单位毫秒,默认SQL被执行时刷新
size:引用数目,最大存储对象数目
readOnly:只读,意味着缓存数据只能读取而不能修改。优点:可以快速读取缓存。缺点:没办法修改缓存,默认值为false
自定义缓存
1.实现org.apache.ibatis.cache.Cache接口
2.配置自定义缓存:<cache type="自定义cache实现类"/>
3.(可选)设置自定义缓存参数
<cache type="">
<property name="host" value="localhost"/>
</cache>
4.(可选)映射器上可以配置缓存规则
eg. <select ... flushCache="flase" useCache="true"/>
二、事务
(一)spring事务管理
spring事务管理是通过springAOP实现的。
1.事务传播机制(propagation)
(1)REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
(2)SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。
(3)NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。
(4)REQUIRESNEW:总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
(5)MANDATORY:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
(6)NEVER:总是非事务地执行,如果存在一个活动事务,则抛出异常
(7)NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。
2.事务隔离级别
ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
另外四个与JDBC的隔离级别相对应:
(1)ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
(2)ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另一个事务读取。
(3)ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
(4)ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。
(二)mybatis和spring整合管理事务(使用springAOP)
applicationContext.xml配置
<!-- 配置jdbc事务管理器,完成数据的完整性和一致性 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
使用注解方式添加事务:
@Transactional(value="transactionManager",propagation=Propagation.REQUIRES_NEW,isolation=Isolation.READ_COMMITTED)
|
属性 |
类型 |
描述 |
| value | String |
可选的限定描述符,指定使用的事务管理器 |
|
propagation |
enum: Propagation |
可选的事务传播行为设置 |
|
isolation |
enum: Isolation |
可选的事务隔离级别设置 |
|
readOnly |
boolean |
读写或只读事务,默认读写 |
|
timeout |
int (in seconds granularity) |
事务超时时间设置 |
|
rollbackFor |
Class对象数组,必须继承自Throwable |
导致事务回滚的异常类数组 |
|
rollbackForClassName |
类名数组,必须继承自Throwable |
导致事务回滚的异常类名字数组 |
|
noRollbackFor |
Class对象数组,必须继承自Throwable |
不会导致事务回滚的异常类数组 |
|
noRollbackForClassName |
类名数组,必须继承自Throwable |
不会导致事务回滚的异常类名字数组 |
注意:
1.在需要事务管理的地方加@Transactional 注解。@Transactional 注解可以被应用于接口定义和接口方法、类定义和类的 public 方法上。
2.通过元素的 “proxy-target-class” 属性值来控制是基于接口的还是基于类的代理被创建。如果 “proxy-target-class” 属值被设置为 “true”,那么基于类的代理将起作用(这时需要CGLIB库cglib.jar在CLASSPATH中)。如果 “proxy-target-class” 属值被设置为 “false” 或者这个属性被省略,那么标准的JDK基于接口的代理将起作用。
3.Spring团队建议在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。在接口上使用 @Transactional 注解,只能当你设置了基于接口的代理时它才生效。因为注解是 不能继承 的,这就意味着如果正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装。
4.@Transactional 的事务开启,或者是基于接口的或者是基于类的代理被创建。所以在同一个类中一个方法调用另一个方法有事务的方法,事务是不会起作用的。
三、插件
使用插件会修改mybatis的底层封装,需要去掌握mybatis的四大对象协作过程和插件的实现原理
插件开发过程:
1.确定需要拦截的签名:
确定要拦截的对象:Executor、StatementHandler、ParameterHandler、ResultHandler;
拦截方法和参数;
eg.拦截修改需要执行的SQL语句
@Intercepts({@Signature(
type=StatementHandler.class,
method="prepare",
args={Connection.class,Integer.class}
)})
public class MyPlugin implements Interceptor{
...
}
@Intercepts 说明它是拦截器
@Signature 注册拦截器签名的地方:
type:是四大对象中的一个
method:要拦截四大对象的某一种接口方法
args:表示该参数的方法
2.实现拦截方法
@Intercepts({@Signature(
type=StatementHandler.class,
method="prepare",
args={Connection.class,Integer.class}
)})
public class MyPlugin implements Interceptor{
Properties props=null;
@Override
public Object intercept(Invocation invocation) throws Throwable {
//如果当前代理的是一个非代理对象,那么它就会调用真实拦截对象的方法,若不是它会调用下个插件代理对象的invoke方法
Object obj=invocation.proceed();
return obj;
}
/*
* 生成对象的代理,这里常用Mybatis提供的Plugin类的wrap方法
* target:被代理的对象
*/
@Override
public Object plugin(Object target) {
//使用mybatis提供的plugin类生成代理对象
return Plugin.wrap(target,this);
}
/*
* 获取插件配置的属性,我们在mybatis的配置文件里去配置
*/
@Override
public void setProperties(Properties properties) {
// TODO Auto-generated method stub
this.props=properties;
}
}
3.配置和运行
<plugins>
<plugin interceptor="xxx.MyPlugin">
<property name="dbType" value="derby"/>
</plugin>
</plugins>
(四)mybatis缓存、事务、插件的基本知识的更多相关文章
- 记录一次mybatis缓存和事务传播行为导致ut挂的排查过程
起因 rhea项目有两个ut一直都是挂的,之前也经过几个同事排查过,但是都没有找到解决办法,慢慢的这个问题就搁置了.因为之前负责rhea项目的同事离职,我临时接手了这个项目,刚好最近来了一个新同事在做 ...
- 【转】MaBatis学习---源码分析MyBatis缓存原理
[原文]https://www.toutiao.com/i6594029178964673027/ 源码分析MyBatis缓存原理 1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 ...
- MyBatis学习总结(四)——MyBatis缓存与代码生成
一.MyBatis缓存 缓存可以提高系统性能,可以加快访问速度,减轻服务器压力,带来更好的用户体验.缓存用空间换时间,好的缓存是缓存命中率高的且数据量小的.缓存是一种非常重要的技术. 1.0.再次封装 ...
- 手写mybatis框架-增加缓存&事务功能
前言 在学习mybatis源码之余,自己完成了一个简单的ORM框架.已完成基本SQL的执行和对象关系映射.本周在此基础上,又加入了缓存和事务功能.所有代码都没有copy,如果也对此感兴趣,请赏个Sta ...
- Mybatis系列(四):Mybatis缓存
一.MyBatis缓存介绍 MyBatis 提供了一级缓存和二级缓存的支持 1. 一级缓存: 默认开启,基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Se ...
- Spring Boot -- Spring Boot之@Async异步调用、Mybatis、事务管理等
这一节将在上一节的基础上,继续深入学习Spring Boot相关知识,其中主要包括@Async异步调用,@Value自定义参数.Mybatis.事务管理等. 本节所使用的代码是在上一节项目代码中,继续 ...
- 【转】MyBatis缓存机制
转载:https://blog.csdn.net/bjweimengshu/article/details/79988252. 本文转载自公众号 美团技术点评 前言 MyBatis是常见的Java数据 ...
- Gradle 1.12用户指南翻译——第四十八章. Wrapper 插件
本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...
- Mybatis:缓存,动态SQL,注解SQL以及动态标签使用
1 转义字符 字符 转义 描述 < < 小于 <= <= 小于等于 > > 大于 >= >= 大于等于 <> <> 不等于 &a ...
随机推荐
- Ubuntu---不能打开 exfat 文件系统格式的 U盘解决方法
出现问题:今天把 U 盘插入 Ubuntu 系统的电脑中,打开 U 盘发现弹出 系统格式不支持 的提醒,无法进入 U 盘进行操作. 环境: Ubuntu18.04 TSL; 格式化为 exfat 文件 ...
- 记录华为、魅族手机无法打印 Log 日志的问题
http://yifeng.studio/2017/02/26/android-meizu-huawei-not-log/ 实测 MEIZU PRO 6 :打开[设置]中的[开发者选项],页面底部找到 ...
- 配对t检验
- Python 爬虫 爬取图片入门
爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本. 用户看到的网页实质是由 HTML 代码构成的,爬 ...
- 理解python的可变参数
以 str.format(*args,**kwargs) 为例. "type1:{},{},{},{}_type2:{a},{b},{c},{d}".format('a',2,*[ ...
- 【学习笔记】 2-SAT问题
Algorithm Description \(2-SAT\)问题就是给定一串布尔变量,每个变量只能为真或假. 要求对这些变量进行赋值,满足布尔方程. 会有一些形如 \(x_1||x_2\) 或者 \ ...
- tensorflow(五)
一.单机编程框架 单机程序是指启动和运行都在一台机器的一个进程中完成,因为没有网络开销,非常适合参数不多.计算量小的模型. 步骤,创建单机数据流图,创建并运行单机会话. saver = tf.trai ...
- framebuffer 知识点
设备文件是在/dev/目录下设备文件有主设备号,次设备号.当操作设备文件, 系统会根据设备文件的设备号找到相应的设备驱动(驱动在内核注册时已指定使用的设备号),并调用相应的功能. open ---& ...
- 二十七、rsync同步工具
1.什么是rsync? Rsync是一款开源的.快速的,多功能的,可实现全量及增量的本地或者远程数据同步备份的优秀工具.windows和linux都可以. 官网:http:www.samba.org/ ...
- space sniffer
space sniffer 一款检测本地磁盘文件占用情况的工具,高效,快速.