mybatis 是一款优秀的持久层框架,简化数据库操作,包括数据库连接创建、返回结果集处理,支持动态sql,使用户可以只关心业务sql。
示例:
用户提供简单的配置文件后,就能实现对数据库操作。
java
// 1、创建SqlSessionFactory对象
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2、由SqlSessionFactory创建一个SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3、通过SqlSession执行对应的sql
User user = sqlSession.selectOne("com.gang.mapper.UserMapper.selectUserById", 1);
System.out.println(user);
核心流程
1、创建SqlSessionFactory
SqlSessionFactory作用是于生产sqlSession对象,与数据库创建连接。主要涉及配置文件的加载解析,对应mapper文件的解析。解析后数据将存储在核心对象Configuration中。你面包括了几乎所有的配置文件内容以及加载的mapper文件。配置文件中大部分配置有默认值,若是配置文件中有指定则会覆盖对应配置。
使用到的设计模式有:建造者模式、工厂模式。建造者模式用来创建复杂对象SqlSessionFactory,包含对配置文件解析封装到Configuration对象中,创建的对象为DefaultSqlSessionFactory里面有个成员变量configuration。


SqlSessionFactory为工厂类用于生产SqlSession

2、创建一个SqlSession对象
涉及事务对象和执行器对象的创建,暂时还没真正创建连接 ,执行器的创建使用到了装饰器模式,若打开了缓存则对执行器进行装饰。

包装后的执行器执行query方法前会执行增强逻辑:判断有没有缓存类cache,再判断缓存中是否有数据,若没有缓存内或者缓存中没有数据在走BaseExecutor中的query

缓存类cache是解析mapper文件时是否添加了cache标签

有标签会添加cache类,cache便签还可以指定自定义缓存类(type属性),需实现Cache接口,若未指定默认为PERPETUAL


PERPETUAL是PerpetualCache的别名,在Configuration类中有指定

一级缓存,默认是PerpetualCache,在每个SqlSession对象内部,作用范围是一次会话内有效。

二级缓存可以自己指定,不指定默认是经过包装后的PerpetualCache。

二级缓存是在Configuration 中存储同时MappedStatement中也持有缓存对象的应用,作用域为进程级别,支持跨session。


一级缓存默认打开,且线程安全。二级缓存需要缓存类自己保证相应规则,Mybatis的cache包下默认提供了10个缓存包装类分别实现不同功能,若想使用可自行选择。

配置文件中settings标签的cacheEnabled是全局性地开启或关闭所有映射器配置文件中已配置的任何缓存(是否打开mapper文件中的cache便签)。因为二级缓存是根据mapper维度设置的,可以使用 使多个mapper共享相同的缓存配置和实例。
3、执行查询返回结果
包含创建数据库连接,执行相应的查询,本处理返回结果,将结果映射为对象。
doQuery方法中会由事务对象的到数据库连接。

若打日志打开了debug连接对象将由ConnectionLogger代理,在执行sql时会打印sql语句。日志实现类可在配置文件中指定,StdOutImpl类将忽略日志等级,所有日志都会打印到控制台。返回列及具体值是trace级日志等级若是debug及以上则不会输出。

Mybatis中的核心类
一、构建初始化阶段(解析配置,生成 SqlSessionFactory)
SqlSessionFactoryBuilder :建造者角色,解析配置输入流,构建出 SqlSessionFactory。
XMLConfigBuilder :解析 mybatis‑config.xml 全局配置文件,生成 Configuration。内部会创建 XMLMapperBuilder 解析各个 Mapper 映射文件。
XMLMapperBuilder :解析 Mapper.xml,解析标签等,生成MappedStatement。
Configuration :【全局大管家】MyBatis 的总配置对象,所有配置全部存在这里。保存 settings、数据源、环境、别名、插件、Mapper 映射、二级缓存集合、所有 MappedStatement。
SqlSessionFactory (接口) & DefaultSqlSessionFactory(实现类):工厂接口,生产 SqlSession。
二、会话层(与应用交互)
SqlSession (接口) & DefaultSqlSession(实现类):对外提供 CRUD 方法:selectOne、selectList、update、insert、delete、commit、rollback、close。持有:Configuration、Executor、一级缓存localCache。生命周期:请求 / 方法级别,用完关闭(一级缓存 PerpetualCache 就在 DefaultSqlSession 内部)。
MapperProxyFactory :生成 Mapper 代理对象。
MapperProxy :实现InvocationHandler,代理 Mapper 接口方法,方法调用转发给sqlSession。
调用 mapper 接口方法本质:mapperProxy.invoke() → 调用sqlSession.selectOne/selectList。
三、事务相关
Transaction(接口) & JdbcTransaction(实现):管理 JDBC Connection;延迟获取连接。
openSession 创建 Transaction 对象,但此时不拿连接;真正执行 SQL 才去 DataSource 拿 Connection。
TransactionFactory:生产 Transaction 对象;JdbcTransactionFactory。
四、Executor 执行器层(MyBatis 核心调度,装饰器模式)
Executor(接口):核心方法:query()、update()、commit()、rollback()。
实现类:
BaseExecutor:抽象基类,实现一级缓存逻辑。
SimpleExecutor:默认,每执行一次语句创建新 Statement。
ReuseExecutor:复用 Statement 对象。
BatchExecutor:批量操作,批量提交。
CachingExecutor:装饰器,负责二级缓存逻辑,包装上面 3 种 Executor。
openSession 中 configuration.newExecutor():cacheEnabled=true,就用 CachingExecutor 包装底层执行器。
五、缓存相关
Cache(接口):缓存统一接口。
PerpetualCache:默认底层实现,内部 HashMap。
装饰实现:LruCache、SynchronizedCache、LoggingCache(二级缓存多层装饰)。
CacheKey:缓存 key 对象,由 sql、参数、分页、环境等信息组合生成,用于一二级缓存 key。
六、Statement 处理器、参数、结果集处理器(三大处理器)
StatementHandler(接口):封装 JDBC Statement 操作。
实现:PreparedStatementHandler(最常用)、SimpleStatementHandler、CallableStatementHandler。
职责:创建 prepareStatement,调用下面两个处理器。
ParameterHandler:设置 SQL 参数,把 Java 参数填充到 PreparedStatement。对应日志打印 Parameters。
ResultSetHandler:处理 JDBC ResultSet 结果集,封装为 Java 实体对象。
三大处理器都会经过插件拦截链,MyBatis 插件就是拦截这四个对象:Executor、StatementHandler、ParameterHandler、ResultSetHandler。
七、映射对象
MappedStatement:保存一条 SQL 的全部元数据,每个<select/update>标签对应一个 MappedStatement。
里面包含:sql、参数类型、返回类型、cache、sqlCommandType 等。存放在 Configuration。
BoundSql:保存解析完成的 SQL(? 占位符 sql)、参数映射信息。动态 SQL 解析后生成 BoundSql。
八、Spring 整合特有类(补充)
SqlSessionTemplate:Spring 对 SqlSession 的代理,线程安全;内部持有SqlSessionFactory。
不会真正关闭自身,通过 ThreadLocal 绑定 SqlSession。
结构图:
java
SqlSessionFactoryBuilder.build(inputStream)
→XMLConfigBuilder解析 →Configuration
SqlSessionFactory.openSession()
→创建Transaction
→Configuration.newExecutor() 得到CachingExecutor/SimpleExecutor
→new DefaultSqlSession
SqlSession.selectOne()
→MapperProxy代理调用
→Executor.query()(一二级缓存)
→StatementHandler
→ParameterHandler 设置参数
→ResultSetHandler 封装结果```