MyBatis源码流程

自动扫描

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
MybatisAutoConfiguration(@ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX))

- MapperScannerRegistrarNotFoundConfiguration
- AutoConfiguredMapperScannerRegistrar
- MapperScannerConfigurer
- ClassPathMapperScanner
# 生成 SqlSessionFactory(通过 SqlSessionFactoryBean)
- org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration#sqlSessionFactory
# 配置 Configuration
- org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration#applyConfiguration
# 生成 SqlSessionTemplate
- org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration#sqlSessionTemplate

@MapperScans
- MapperScannerRegistrar
- MapperScannerConfigurer
- ClassPathMapperScanner

# 扫描
ClassPathMapperScanner
# 扫描
- doScan
# spring 扫描
- super.doScan()
# beanDefinition 处理
- void processBeanDefinitions()
# 设置 BeanClass(MapperFactoryBean.class, 每个 Mapper 接口, 就是一个对象)
- definition.setBeanClass(this.mapperFactoryBeanClass);


Configuration
# 获取所有拦截器
- List<Interceptor> getInterceptors()
# 根据全限定名获取对应的 MappedStatement
- MappedStatement getMappedStatement(String id)
# 获取 Mapper 对象
- T getMapper(Class<T> type, SqlSession sqlSession)
# 创建执行器(默认: new CachingExecutor(SimpleExecutor))
- Executor newExecutor(Transaction transaction)
# 获取 StatementHandler
- StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
# 创建默认 StatementHandler
- new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql)
# 绑定拦截器
- interceptorChain.pluginAll(statementHandler);

Mapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# Mapper 实体对象
MapperFactoryBean extends SqlSessionDaoSupport implements FactoryBean<T>
# 初始化后回调, 将此对象注册到 Configuration(父类实现了 InitializingBean#afterPropertiesSet)
- checkDaoConfig
# 获取对象(实现了 Spring FactoryBean)
- T getObject()
# 从 SqlSession(SqlSessionTemplate) 中获取对应的 Mapper
- getSqlSession().getMapper(this.mapperInterface)


# Mapper 容器
MapperRegistry
# 将 Mapper 类添加到容器内
- void addMapper(Class<T> type)
# 根据 Mapper 生成 MapperProxyFactory 放入容器内
- knownMappers.put(type, new MapperProxyFactory<>(type))
# 从容器中获取 Mapper 对象(有缓存)
- T getMapper(Class<T> type, SqlSession sqlSession)
# 代理工厂生产代理
- mapperProxyFactory.newInstance(sqlSession)


# Mapper 对象代理工厂
MapperProxyFactory
# 自动生成 Mapper 对象代理(MapperProxy)
- T newInstance(SqlSession sqlSession)


# Mapper 代理对象
MapperProxy
# 执行方法
- org.apache.ibatis.binding.MapperProxy#cachedInvoker
# PlainMethodInvoker#invoke
- org.apache.ibatis.binding.MapperProxy.PlainMethodInvoker#invoke
# MapperMethod 执行
- org.apache.ibatis.binding.MapperMethod#execute

# SqlSession 执行对应的方法
- sqlSession.xxx

SqlSession

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# 增删改查对象抽象
SqlSession
- <T> T selectOne(String statement)
- <E> List<E> selectList(String statement);
- int insert(String statement);
- int update(String statement);
- <T> T getMapper(Class<T> type)
- ...


# 会话工厂
SqlSessionFactory
- SqlSession openSession() 开启会话
- Configuration getConfiguration() 获取配置

# 会话工厂 Bean
SqlSessionFactoryBean(DefaultSqlSessionFactory)
# 获取对象
- SqlSessionFactory getObject()
# 执行初始化
- SqlSessionFactory buildSqlSessionFactory()
# 解析 xml(会将所有的 mapper 放入 Configuration)
- org.apache.ibatis.builder.xml.XMLMapperBuilder#parse

# 将 mapper 放入 Configuration
- org.apache.ibatis.builder.xml.XMLMapperBuilder#bindMapperForNamespace


# 默认会话工厂
DefaultSqlSessionFactory
# 开启会话
- SqlSession openSession()
- SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit)
# 根据事务工厂获取事务
- transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit)
# 创建执行器(默认是开启缓存的, new CachingExecutor(SimpleExecutor))
- Executor executor = configuration.newExecutor(tx, execType)
# 创建会话增删改查对象
- new DefaultSqlSession(configuration, executor, autoCommit);

#增删改查对象模板
SqlSessionTemplate implements SqlSession
# 初始化配置 SqlSession 代理(SqlSessionInterceptor)
- sqlSessionProxy = newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[] { SqlSession.class }, new SqlSessionInterceptor())

# 父类方法实现(通过生成的代理来实现)
- this.sqlSessionProxy.selectOne()

# 根据类获取 Mapper 对象
- T getMapper(Class<T> type)
# 从 Congifuration 中获取 Mapper 对象
- getConfiguration().getMapper(type, this);


# 默认的增删改查对象
DefaultSqlSession
# 查询 list
- org.apache.ibatis.session.defaults.DefaultSqlSession#selectList
# 通过 Configuration 获取 MapperStatement
- MappedStatement ms = configuration.getMappedStatement(statement)
# 执行器执行查询
- executor.query(ms, wrapCollection(parameter), rowBounds, handler)

# 更新
- org.apache.ibatis.session.defaults.DefaultSqlSession#selectList
# 通过 Configuration 获取 MapperStatement
- MappedStatement ms = configuration.getMappedStatement(statement)
# 执行器执行更新
- executor.update(ms, wrapCollection(parameter));


# 增删改查对象拦截器
SqlSessionInterceptor implements InvocationHandler
# 执行
- public Object invoke(Object proxy, Method method, Object[] args)
# 开启会话
- org.mybatis.spring.SqlSessionUtils#getSqlSession
# 执行代理方法(MapperMethod#execute)
- Object result = method.invoke(sqlSession, args);
# 提交会话(回滚)
- sqlSession.commit(true);
# 结束会话
- org.mybatis.spring.SqlSessionUtils#closeSqlSession

Executor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# 缓存 key
CacheKey
[msId, offset, limit, sql, param..., environmnetId]


# 执行器
Executor
# 查询
- List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql)
# 更新
- int update(MappedStatement ms, Object parameter)
# 提交
- void commit(boolean required)
# 回滚
- void rollback(boolean required)
# 获取事务
- Transaction getTransaction()

# 基础执行器模板
BaseExecutor implements Executor
# 提交
- void commit(boolean required)
# 清除一级缓存
- clearLocalCache();
# 提交事务
- transaction.commit();
# 回滚
- void commit(boolean required)
# 清除一级缓存
- clearLocalCache();
# 提交事务
- transaction.commit();
# 更新
- int update(MappedStatement ms, Object parameter)
# 清楚缓存
- clearLocalCache();
# 回调子类实现 更新
- doUpdate(ms, parameter);
# 查询
- List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler)
# 根据 MappedStatement 获取 BoundSql
- BoundSql boundSql = ms.getBoundSql(parameter);
# 获取缓存 key
- CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql);
# 底层查询
- List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
# 如果一级缓存命中, 则返回数据
- list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;
# 从 db 查询数据
- list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
# 如果一级缓存范围是 STATEMENT 则清楚缓存
- clearLocalCache();
# 从 db 查询数据
- List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
# 回调子类实现 查询
- list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
# 将结果放入一级缓存
- localCache.putObject(key, list);

# 默认基础执行器
SimpleExecutor extends BaseExecutor
# 预执行
- Statement prepareStatement(StatementHandler handler, Log statementLog)
# 打开会话连接
- Connection connection = getConnection(statementLog);
# 执行 db 预编译
- stmt = handler.prepare(connection, transaction.getTimeout());
# 执行参数处理(#{}, ${} 值处理)
- handler.parameterize(stmt);
# 更新
- doUpdate(MappedStatement ms, Object parameter)
# 预执行
- stmt = prepareStatement(handler, ms.getStatementLog());
# 真实执行(db 级别调用)
- handler.update(stmt);
# 查询
- List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
# 预执行
- stmt = prepareStatement(handler, ms.getStatementLog());
# 真实执行(db 级别调用)
- handler.update(stmt);


# 二级缓存执行器(装饰器模式)
CachingExecutor implements Executor
# 增加了二级缓存, 以 MappedStatement 为纬度

Statement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
StatementType
# 直接操作 sql, 不执行预编译, 直接获取数据
- STATEMENT ${}
# 预编译, 执行预编译, 然后获取数据
- PREPARED #{}
# 存储过程
- CALLABLE


# 语句处理器(和 db 进行交互)
StatementHandler
# 预编译
- Statement prepare(Connection connection, Integer transactionTimeout)
# 参数处理(${}, #{}, TypeHandler#setParameter)
- void parameterize(Statement statement)
# 更新
- int update(Statement statement)
# 查询
- List<E> query(Statement statement, ResultHandler resultHandler)
# 获取 sql
- BoundSql getBoundSql();
# 获取参数处理器
- ParameterHandler getParameterHandler();


# 基础抽象语句处理器
BaseStatementHandler implements StatementHandler
# 解析 boundSql, 绑定 参数处理器, 绑定 结果处理器
- protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)


# 预编译语句处理器
PreparedStatementHandler extends BaseStatementHandler
# 更新
- int update(Statement statement)
# 执行db 调用
- ps.execute();
# 响应更新行数(int)
- int rows = ps.getUpdateCount();
# keyGenerator 处理(自增主键)
- keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
# 查询
- List<E> query(Statement statement, ResultHandler resultHandler)
# 执行db 调用
- ps.execute();
# 结果处理器(TypeHandler#getResult)
- resultSetHandler.handleCursorResultSets(ps);

Plugin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 拦截器
Interceptor
# 拦截处理
- Object intercept(Invocation invocation)
# 默认包装
- default Object plugin(Object target) return Plugin.wrap(target, this);


# 插件
Plugin implements InvocationHandler
# 将拦截器和原始对象包装到一块
- Object wrap(Object target, Interceptor interceptor)
# 执行
- org.apache.ibatis.plugin.Plugin#invoke
# 执行拦截器
- interceptor.intercept(new Invocation(target, method, args));


拦截范围:
1. ParameterHandler
1. ResultSetHandler
1. StatementHandler
1. Executor

MyBatis源码流程
https://gallrax.github.io/2023/04/10/MyBatis源码流程/
作者
Gallrax
发布于
2023年4月10日
许可协议