mybatis的初始化过程:
1.调用SqlSessionFactoryBuilder对象的build方法
2.SQlSessionFactoryBuilder根据输入流对象等信息创建XMLConfigBuilder对象
3.SQlSessionFactoryBuilder调用XMLConfigBuilder对象的parse方法
4.XmlConfigBuilder对象解析mybatis配置文件生存Configuration对象
5.SqlSessionFactoryBuilder根据Configuration对象创建DefaultSessionFactory对象
6.使用DefaultSessionFactory对象创建sqlSession对象,从而完成mybatis的初始化过程
MyBatis的事务管理分为两种形式:
1.使用JDBC的事务管理机制:即利用java.sql.Connection对象完成对事务的提交(commit())、回滚(rollback())、关闭(close())等
JdbcTransaction直接使用JDBC的提交和回滚事务管理机制 。它依赖与从dataSource中取得的连接connection 来管理transaction 的作用域,connection对象的获取被延迟到调用getConnection()方法。如果autocommit设置为on,开启状态的话,它会忽略commit和rollback
2.使用MANAGED的事务管理机制:这种机制MyBatis自身不会去实现事务管理,而是让程序的容器如(JBOSS)来实现对事务的管理
ManagedTransaction让容器来管理事务Transaction的整个生命周期,意思就是说,使用ManagedTransaction的commit和rollback功能不会对事务有任何的影响,它什么都不会做,它将事务管理的权利移交给了容器来实现
mybatis的一级缓存
mybatis的一级缓存是sqlsession级别的缓存,用户不用配置,自动支持
mybatis一级缓存的工作流程:
1.对于某个查询,根据statementId,rowBounds,params来构建一个key构建(构建key的逻辑在BaseExecutor的createCacheKey方法里面),然后根据这个key去cache中取出对应的key储存的结果值;
2.判断从cache中根据特定key取出的数据是否为空,看是否命中;
3.如果命中,则直接返回缓存结果;
4.如果没有命中:
4.1 去数据库中查询数据,得到查询结果
4.2 根据key和查询到的结果做为key,value储存cache中
4.3 将查询结果返回
mybatis中Cache接口的定义以及CacheKey的定义
mybatis定义了一个org.apache.ibatis.cache.Cache接口做为cache提工作的SPI,所有的mybatis的缓存都实现这一个接口,mybatis定义了一个基于HashMap的实现类PerpetualCache,在sqlSession对象的Executor对象中维护的Cache类型的对象,就是该类的一个具体的实现。
由于mybatis的一级缓存是用简单的HashMap实现,因此如何确定MAP的key值成了一级缓存中最核心的问题。换句话说就是如何确定两次查询是完全相同的查询成了一级缓存要解决的核心问题。
MyBatis认为,对于两次查询,如果一下条件完全一样,那么就认为他们是完全相同的两次查询。
1.传入的statementId相同
2.查询中要求的结构及中的结果范围一样(结果范围通过rowBounds.offset以及rowBounds.limit表示)
3.两次查询的boundSQL.getSql()相同
4.传递给Statement的要设置的参数相同
因此CacheKey由一下条件决定:statementId+RowBounds+传递给JDBC的SQL+传递给JDBC的参数
一级缓存存在的问题以及注意事项
1.一级缓存是一个粗力度的缓存,没有更新缓存一级缓存过期的概念
2.一级缓存使用了简单的HashMap的实现并且没有对map的大小一级容量做限制,极端情况下可能出现OutOfMemoryError错误,Mybatis之所以这么设计是因为
2.1 一般sqlsession的生存时间很短,一般情况下使用一个sqlsession不会执行太多的操作
2.2 对于一个sqlsession而言,只要执行update操作,就会清除一级缓存中的内容一般不会出现缓存过大的情况
2.3 可以手动清除sqlsession对象中的缓存。
3.对于只执行且频繁执行大范围的select操作的sqlsession对象,其生存时间不要过长
4.对于数据变化频率很大并且要求高实时性的数据,要控制好sqlsession的生存时间。
mybatis的二级缓存
mybatis的二级缓存是Application级别的缓存,他可以提高对数据库的查询效率,从而提高应用的性能。
我们知道,当mybatis开启一次回话的时候一个sqlsession使用一个executor对象来完成会话的操作,mybatis的二级缓存的关键就是对这个executor对象做文章,如果用户设置了“cacheEnabled=true”,mybatis在为sqlsession对象创建executor对象的时候会使用装饰器模式为executor添加一个装饰器CachingExecutor,这是sqlsession使用CachingExecutor完成操作,CachingExecutor会先判断查询请求在Application的二级缓存中是否有缓存结果,如果有则直接返回查询结果,否则使用executor对象完成查询操作,之后cachngExecutor将executor的换回结果添加到二级缓存,并返回给用户。
mybatis二级缓存划分
1.为每一个Mapper分配一个Cache缓存对象
2.多个Mapper公用一个Cache缓存对象
mybatis自身支持的二级缓存实现
1.LRU
2.FIFO
3.Scheduled
二级缓存存在的问题
1.对于某些使用了关联查询的查询,如果其关联的表的数据发生了更新,由于缓存了关联查询更新之前的数据,到时查询数据和真实数据不一致。
解决方案:自定义mybatis插件,以更细的粒度控制二级缓存
Mapper XML文件使用总结:
SQL映射文件的顶级元素有:
1.cache 缓存配置
2.cache-ref 缓存应用配置
3.resultMap 结果集映射
4.sql 能被其他语句引用的sql代码块
5.insert 映射插入语句
6.update 映射更新语句
7.delete 映射删除语句
8.select 映射查询语句
动态SQL:if,choose(when,otherwise),trim(where,set),foreach