mybatis3.5.x源码系列
Posted xxzblog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis3.5.x源码系列相关的知识,希望对你有一定的参考价值。
- 首先我们了解一下mybatis中的几个核心概念
- Configuration 配置,可以理解为mybatis的大管家,管理一切
- Environment 环境,这个主要负责数据源,事务管理器
- MappedStatement mapper.xml对应的声明类,定义mapper中所有的标签,属性
- MapperRegistry Mapper注册器,管理编写的mapper类和mapper.xml
- InterceptorChain 拦截器链,管理所有拦截器,也就是我们常用的mybatis插件
- SqlSessionFactory SQL会话管理工厂类
- SqlSession SQL会话,定义了增,删,改,查,提交,回滚,获取java.sql.Connection,获取mapper
- Executor 执行器,主要负责增,删,改,查,提交,回滚的执行
- MapperProxy mapper代理类,生成接口代理对象
带着上面的概念,我们开始我们的源码分析入门之旅
- 首先我们要看看官方demo 打开mybatis-3-getting-started
例子:
代码结构:
src
main
test
java
io.jsbxyyx
mapper
Blog.java
BlogMapper.java
BlogMapper.xml
Demo.java
mybatis-config.xml
public static void main(String[] args) throws IOException
String resource = "io/jsbxyyx/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
BlogMapper blogMapper = sqlSessionFactory.openSession().getMapper(BlogMapper.class);
Blog blog = blogMapper.selectBlog(1L);
System.out.println(blog);
XML创建SqlSessionFactory
org.apache.ibatis.session.SqlSessionFactoryBuilder#build(java.io.InputStream, java.lang.String, java.util.Properties)
》org.apache.ibatis.builder.xml.XMLConfigBuilder#parse()
》org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration(org.apache.ibatis.parsing.XNode root)
》org.apache.ibatis.session.SqlSessionFactoryBuilder#build(org.apache.ibatis.session.Configuration)
核心方法org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration
该方法会解析出properties,settings,typeAliases,plugins,objectFactory,objectWrapperFactory,reflectorFactory,environments,databaseIdProvider,typeHandlers,mappers
解析mappers
// 这里解析mappers下的package标签,也就是包扫描,以及mapper标签
org.apache.ibatis.builder.xml.XMLConfigBuilder#mapperElement(org.apache.ibatis.parsing.XNode parent)
》org.apache.ibatis.builder.xml.XMLStatementBuilder#parseStatementNode
》org.apache.ibatis.builder.MapperBuilderAssistant#addMappedStatement
解析mappers,创建MappedStatement并缓存到内存
打开session
org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSession()
》org.apache.ibatis.session.Configuration#getDefaultExecutorType()
》org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource(org.apache.ibatis.session.ExecutorType execType, org.apache.ibatis.session.TransactionIsolationLevel level, boolean autoCommit)
》org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#getTransactionFactoryFromEnvironment(org.apache.ibatis.mapping.Environment)
》org.apache.ibatis.transaction.TransactionFactory#newTransaction(javax.sql.DataSource, org.apache.ibatis.session.TransactionIsolationLevel, boolean)
》org.apache.ibatis.transaction.jdbc.JdbcTransaction#JdbcTransaction(javax.sql.DataSource, org.apache.ibatis.session.TransactionIsolationLevel, boolean)
》org.apache.ibatis.session.Configuration#newExecutor(org.apache.ibatis.transaction.Transaction, org.apache.ibatis.session.ExecutorType)
》org.apache.ibatis.session.defaults.DefaultSqlSession#DefaultSqlSession(org.apache.ibatis.session.Configuration, org.apache.ibatis.executor.Executor, boolean)
流程
获取数据源 =》开启事务 =》获取执行器 =》创建SqlSession
获取Mapper
org.apache.ibatis.session.Configuration#getMapper(java.lang.Class<T>, org.apache.ibatis.session.SqlSession)
》org.apache.ibatis.binding.MapperRegistry#getMapper(java.lang.Class<T>, org.apache.ibatis.session.SqlSession)
》org.apache.ibatis.binding.MapperProxyFactory#newInstance(org.apache.ibatis.session.SqlSession)
》java.lang.reflect.Proxy#newProxyInstance(java.lang.ClassLoader loader, java.lang.Class<?>[] interfaces, java.lang.reflect.InvocationHandler h)
流程
根据接口class =》创建JDK动态代理对象org.apache.ibatis.binding.MapperProxy(这就是为啥mybatis的mapper定义是接口的原因)
执行方法
io.jsbxyyx.mapper.BlogMapper#selectBlog
》org.apache.ibatis.binding.MapperProxy#invoke
》org.apache.ibatis.binding.MapperProxy#cachedInvoker
》org.apache.ibatis.binding.MapperMethod#MapperMethod(java.lang.Class<?> mapperInterface, java.lang.reflect.Method method, org.apache.ibatis.session.Configuration config)
》org.apache.ibatis.binding.MapperProxy.PlainMethodInvoker#invoke
》org.apache.ibatis.binding.MapperMethod#execute(org.apache.ibatis.session.SqlSession, java.lang.Object[] args)
》org.apache.ibatis.session.Configuration#getMappedStatement(java.lang.String statement)
》org.apache.ibatis.executor.Executor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
》org.apache.ibatis.executor.CachingExecutor#createCacheKey(org.apache.ibatis.mapping.MappedStatement, java.lang.Object parameterObject, org.apache.ibatis.session.RowBounds, org.apache.ibatis.mapping.BoundSql)
》org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
》org.apache.ibatis.executor.BaseExecutor#queryFromDatabase(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
》org.apache.ibatis.executor.SimpleExecutor#doQuery(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.mapping.BoundSql)
》org.apache.ibatis.executor.statement.RoutingStatementHandler#RoutingStatementHandler(org.apache.ibatis.executor.Executor, org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.mapping.BoundSql)
》org.apache.ibatis.session.Configuration#newParameterHandler(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.mapping.BoundSql)
》org.apache.ibatis.scripting.LanguageDriver#createParameterHandler
》org.apache.ibatis.plugin.InterceptorChain#pluginAll(parameterHandler)
》org.apache.ibatis.session.Configuration#newResultSetHandler(org.apache.ibatis.executor.Executor, org.apache.ibatis.mapping.MappedStatement, org.apache.ibatis.session.RowBounds, org.apache.ibatis.executor.parameter.ParameterHandler, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.mapping.BoundSql)
》org.apache.ibatis.executor.resultset.DefaultResultSetHandler
》org.apache.ibatis.plugin.InterceptorChain#pluginAll(resultSetHandler)
》org.apache.ibatis.plugin.InterceptorChain#pluginAll(statementHandler)
》org.apache.ibatis.executor.SimpleExecutor#prepareStatement(org.apache.ibatis.executor.statement.StatementHandler, org.apache.ibatis.logging.Log)
》org.apache.ibatis.transaction.Transaction#getConnection
》org.apache.ibatis.transaction.jdbc.JdbcTransaction#openConnection
》org.apache.ibatis.executor.statement.StatementHandler#query(java.sql.Statement, org.apache.ibatis.session.ResultHandler)
》java.sql.PreparedStatement#execute
》org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleResultSets(java.sql.Statement)
流程
动态代理MapperProxy =》创建MappedStatement缓存key =》获取Executor =》分别加载parameter,resultSet,statement插件 =》 获取java.sql.Connection =》获取java.sql.Statement =》执行sql =》处理结果集
流程结束。
期待下次更新咯。😄
以上是关于mybatis3.5.x源码系列的主要内容,如果未能解决你的问题,请参考以下文章