(四)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 ...
随机推荐
- JS面向对象,原型,继承
ECMAScript有两种开发模式:1.函数式(过程化),2.面向对象(OOP).面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.但是,ECMAScript ...
- Pmw大控件
Python大控件——Pmw——是合成的控件,以Tkinter控件为基类,是完全在Python内写的.它们可以很方便地增加功能性的应用,而不必写一堆代码.特别是,组合框和内部确认计划的输入字段放在一起 ...
- springboot cloud 网盘
boot https://pan.baidu.com/s/12SkGJNu_M-I-pjg-GxqHRw 5uga boot-cloud https://pan.baidu.com/s/1gO ...
- 是时候写个自己的dialog了
组件下载地址:http://pan.baidu.com/s/1pJFVfej 最近做的项目需要用到对话框,但是原生的弹出框你是知道的.如果有时间,还是自己尝试一下,也是可以的. 一个简单图 里面的输入 ...
- JavaEE--调用 WSDL -- httpclient 4.x.x
参考:http://aperise.iteye.com/blog/2223454 http://blog.csdn.net/chenleixing/article/details/43456987 ...
- 吴裕雄--天生自然TensorFlow高层封装:Keras-返回值
# 1. 数据预处理. import keras from keras.models import Model from keras.datasets import mnist from keras. ...
- Kubernetes系列三:二进制安装Kubernetes环境
安装环境: # 三个节点信息 192.168.31.11 主机名:env11 角色:部署Master节点/Node节点/ETCD节点 192.168.31.12 主机名:env12 角色:部署Node ...
- spark安装和使用
local模式 概述 local模式就是在一台计算机上运行spark程序,通常用于在本机上练手和测试,它将线程映射为worker. 1)local: 所有计算都运行在一个线程当中,没有任何并行计算,通 ...
- 2017NOIP模拟赛三 A酱的体育课
据说改编自$CodeM 美团点评编程大赛初赛A 轮$ 简单的水题...考试的时候没想到,xjb打了暴力. 显然,第$x$个人排在第$y$个位置的情况总数为$(n-1)!$,在这些情况中,第$x$人对答 ...
- inotify+rsync实时同步
主服务器上安装inotify和rsync,备用服务器上安装rsync 主服务器上修改/etc/rsyncd.conf配置文件 三. 创建密码文件,防火墙设置,客户端和服务器端都要做如下操作 echo ...