04.MyBatis源码分析之查询操作
01.MyBatis原理分析之SqlSessionFactory
02.MyBatis原理分析之SqlSession
03.MyBatis原理分析MapperProxy
1. Test
2. MapperProxy
- org.apache.ibatis.binding.MapperProxy
2.1 invoke(Object proxy, Method method, Object[] args)
- 如果是 Object 中定义的方法,直接执行。如 toString(),hashCode() 等
2.2 cachedMapperMethod(Method method)
- 其他 Mapper 接口定义的方法交由 mapperMethod 来执行
3. MapperMethod
-
org.apache.ibatis.binding.MapperMethod
-
一系列的构建操作
3.1 MapperMethod(Class<?> mapperInterface, Method method, Configuration config)
3.2 SqlCommand(Configuration configuration, Class<?> mapperInterface, Method method)
3.3 MethodSignature(Configuration configuration, Class<?> mapperInterface, Method method)
4. MapperProxy
-
org.apache.ibatis.binding.MapperProxy
-
调用增删改查方法
5. MapperMethod
-
org.apache.ibatis.binding.MapperMethod
-
根据 xml 配置的不同标签,进入到不同的方法
6. DefaultSqlSession
- org.apache.ibatis.session.defaults.DefaultSqlSession
6.1 selectOne(String statement, Object parameter)
- 查询单个实际上也是查询多个,然后返回一个
6.2 selectList(String statement, Object parameter)
6.3 selectList(String statement, Object parameter, RowBounds rowBounds)
- 根据不同的 executor,可能是 simpleExecutor 也可能是 CachingExecutor,进入到不同的方法里,这里我添加了二级缓存,所以用的是 CachingExecutor
7. CachingExecutor
- org.apache.ibatis.executor.CachingExecutor
7.1 query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler)
7.2 query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
- 先从 tcm(TransactionalCacheManager) 里拿对象,即从二级缓存里拿对象,没有的话则进入 query()
8. BaseExecutor
- org.apache.ibatis.executor.BaseExecutor
8.1 query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
- 先从 localCache 里拿对象,即从一级缓存里拿对象,没有的话则调用 queryFromDatabase()
8.2 queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql
9. SimpleExecutor
- org.apache.ibatis.executor.SimpleExecutor
10. Configuration
- org.apache.ibatis.session.Configuration
11. RoutingStatementHandler
-
org.apache.ibatis.executor.statement.RoutingStatementHandler
-
根据类型判断,这里用的是预编译方式,即 preparedStatement
12. PreparedStatementHandler
- org.apache.ibatis.executor.statement.PreparedStatementHandler
13. BaseStatementHandler
-
org.apache.ibatis.executor.statement.BaseStatementHandler
-
在这里会创建 parameterHandler 和 ResultSetHandler 两大对象,而且会被加载到拦截器中
14. Configuration -> 10
- org.apache.ibatis.session.Configuration
14.1 newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql)
14.2 newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler,ResultHandler resultHandler, BoundSql boundSql)
14.3 newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
15. SimpleExecutor -> 9
- org.apache.ibatis.executor.SimpleExecutor
15.1 doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
- prepareStatement() 就是预编译过程
15.2 prepareStatement(StatementHandler handler, Log statementLog)
- 这里继续往下分析,就会进入到 原生jdbc 的 prepareStatement.setXxx方法(),有木有豁然开朗的感觉
15.3 doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
16. PreparedStatementHandler
-
org.apache.ibatis.executor.statement.PreparedStatementHandler
-
这里就是原生 jdbc 的查询方法,是不是感觉很有成就感。handleResultSets(ps) 其实就是处理结果
17. DefaultResultSetHandler
-
org.apache.ibatis.executor.resultset.DefaultResultSetHandler
-
这个方法没细看,直接看查询结果就知道 mybatis 已经为我们做完了查询
18. Test
19. 一级缓存作用原理
- 一级缓存作用在 8.1 节
20. 二级缓存作用原理
- 二级缓存作用在 7.2 节