
Mybatis是如何操做数据库的
Mybatis操做数据库,能够分为如下五个步骤:sql
- 读取核心配置文件,生成Configuration对象。
- 根据Configuration对象,经过SqlSessionFactoryBuilder,建立SqlSessionFactory工厂对象。
- 使用SqlSessionFactory工厂对象,获取SqlSession实例,SqlSession实例提供了API用于操做数据库。
- Mybatis中使用了JDK动态代理,根据Mapper接口和编写的sql语句,SqlSession实例生成Mapper代理对象。编写的sql,会经过注解或者xml的形式,映射到Mapper对象上的方法。
- 执行Mapper的方法时,Mapper中的方法会调用SqlSession实例的方法,SqlSession实例的方法会调用Executor对象,由Executor对象实际去执行数据库操做,对执行结果封装等。
Mybatis Executor分类

Executor有如下几种:数据库
- BaseExecutor(执行器抽象类),维护一级缓存、管理事务等,对数据的增删改查,则是调用下面3个执行器的(doQuery、doUpdate)方法来完成。
- SimpleExecutor(简单执行器),每次执行SQL须要预编译SQL语句,生成新的预处理器(PreparedStatement)。
- ReuseExecutor(可重用执行器),同一SQL语句执行只须要预编译一次SQL语句,但屡次调用,仍是会查询屡次数据库的
- BatchExecutor(批处理执行器),只针对修改操做的SQL语句预编译一次,而且须要手动提交修改才生效。
- CachingExecutor(二级缓存的缓存执行器),它是对BaseExecutor的一个包装,进一步说,也就是对SimpleExecutor、ReuseExecutor、BatchExecutor进行包装。用于管理二级缓存,而具体的对数据的操做,则是会调用BaseExecutor,由BaseExecutor来完成。
说说Mybatis缓存
Mybatis中会对数据进行缓存。若是同时开启Mybatis的一二级缓存,查询时,会先从二级缓存中查询,若是查询不到,在一级缓存中查询,若是还查询不到,才到数据库中查询。缓存

一级缓存
- 一级缓存是会话级的缓存,即在同个线程屡次查询同一条数据时,除了第一次,其他次查询都能再也不操做数据库,而从缓存中获取数据。
- 若是修改了数据,不须要提交修改,在同个线程就能查到同一条修改的数据。
- 若是修改、添加、删除数据,而且进行commit操做提交了,则缓存会清空。
- Mybatis中一级缓存默认打开的。
- 同一个会话中,在知足如下几个条件时,才能命中缓存,不然仍是会去查数据库。
- 需知足如下运行时要求:
- 在同一个会话中
- sql语句与参数相同
- 相同的statementId
- RowBounds(分页)相同
- 需知足如下配置与操做要求:
- 未手动清空缓存 (提交、回滚)
- 未配置flushCache=true
- 未执行update
- 缓存的做用域不是statement,即做用域不是单次数据库操做
二级缓存
- 二级缓存也称为应用级缓存,它的做用范围是整个应用,便可以跨线程使用。
- 二级缓存适用于一些修改比较少的数据。
- 二级缓存在Mybatis默认不开启。
- 当某某个SqlSession实例执行修改、添加、删除数据,而且进行commit操做提交了。则缓存会清空。
- 二级缓存数据,默认使用自带的PerpetualCache保存在内存和硬盘中,也能够与第三方集成。
- 二级缓存是基于Mapper级别的,每一个Mapper都有本身的二级缓存区域,按照namespace来划分,不一样namespace下的操做互不影响。若是两个Mapper的namespace相同,则共享同个二级缓存区。
- 在知足如下几个运行时条件时,才能命中二级缓存。
- sql语句与参数相同
- 相同的statementId
- RowBounds(分页)相同
Spring整合Mybatis后,Mybatis一级缓存失效?
其实不是失效,而是因为在未开启事务的状况下,在同个线程中,每次查询后Spring都会关闭旧的sqlSession,须要再次查询时再建立新的sqlSession。 不是同个sqlSession,天然不会命中一级缓存。app
在开启事物的状况之下,Spring会使用threadLocal,把当前线程与一个sqlSession实例绑定,重用该sqlSession实例,所以此时一级缓存是有效的。ide