【Mybatis源码剖析】Spring中获取 Mybatis Mapper接口(注解Autowired),并调用过程剖析

程序中获取Mapper接口实例的调用过程

//注解Autowired时,通过getObject()获取对应接口实例
T org.mybatis.spring.mapper.MapperFactoryBean.getObject() throws Exception 
//SqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory)
<T> T org.mybatis.spring.SqlSessionTemplate.getMapper(Class<T> type)
//Configuration 从SqlSessionTemplate.getConfiguration()获取
<T> T org.apache.ibatis.session.Configuration.getMapper(Class<T> type, SqlSession sqlSession)
//对MapperProxyFactory里获取对应接口的MapperProxyFactory<T>
<T> T org.apache.ibatis.binding.MapperRegistry.getMapper(Class<T> type, SqlSession sqlSession)
//JDK动态代理生成实现了T的代理类,对T接口方法进行拦截.为什么要用动态代理?拦截T的所有方法
T org.apache.ibatis.binding.MapperProxyFactory.newInstance(SqlSession sqlSession)
//拦载T接口方法时,创建MapperMethod(SqlCommand,MethodSignature)并缓存
Object org.apache.ibatis.binding.MapperProxy.invoke(Object proxy, Method method, Object[] args) throws Throwable 
//创建MappedMethod时new SqlCommand时,执行以下方法得到Configration中缓存的具体MappedStatement的statementId
MappedStatement org.apache.ibatis.binding.MapperMethod.SqlCommand.resolveMappedStatement(Class<?> mapperInterface, String methodName, Class<?> declaringClass, Configuration configuration)
//执行MapperMethod的execute方法,将拦截到的参数args 与 sqlSessionTemplate往下传,根据
Object org.apache.ibatis.binding.MapperMethod.execute(SqlSession sqlSession, Object[] args)
//根据sqlCommand,MethodSignature的条件,执行sqlSessionTemplate的查询方法,以selectOne方法为例,实则调用代理类的selectOne方法
<T> T org.mybatis.spring.SqlSessionTemplate.selectOne(String statement)   ---虚调用--见下面‘实调用’处-
//为什么要用代理类?答案在SqlSessionInterceptor类的invoke方法
this.sqlSessionProxy = (SqlSession) newProxyInstance(SqlSessionFactory.class.getClassLoader(),new Class[] { SqlSession.class },new SqlSessionInterceptor());
//SqlSessionInterceptor的invoke方法,通过SqlSessionUtils.getSqlSession(sqlSessionFactory,executorType,exceptionTranslator)获取DefaultSqlSession,它才是真实与数据库通信的sqlSession
Object org.mybatis.spring.SqlSessionTemplate.SqlSessionInterceptor.invoke(Object proxy, Method method, Object[] args) throws Throwable
//SqlSessionUtils的getSqlSession方法,两个逻辑:
//1.从sqlSessionFactory获取SqlSessionHolder,从holder获取sqlSession;
Object org.springframework.transaction.support.TransactionSynchronizationManager.getResource(Object key)
//2.直接从sessionFacotry.openSession(ExecutorType)获取sqlSession,并注册绑定sessionHolder供下次使用
Open Declaration   SqlSession org.apache.ibatis.session.SqlSessionFactory.openSession(ExecutorType execType)
void org.mybatis.spring.SqlSessionUtils.registerSessionHolder(SqlSessionFactory sessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator, SqlSession session)
//从Configuration获取Environment
//从Environment环境中获取事务工厂TransactionFactory
//从TransactionFactory获取事务tx
//从Configuration创建执行器Executor(configruation.newExecutor(tx,executorType)),其中Object org.apache.ibatis.plugin.InterceptorChain.pluginAll(Object target)为Executor添加拦截器
//返回new DefaultSqlSession(configuration,executor,autoCommit),这个类才是真正与数据库通信的
SqlSession org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit)
//---实调用---真实调用是通过DefaultSqlSession,而非SqlSessionTemplate(它只是一个带了sqlSessionFactory,exceptiontranslator的工具类)
<T> T org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(String statement, Object parameter)
//根据statement的SqlId,查出MappedStatement
<E> List<E> org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(String statement, Object parameter, RowBounds rowBounds)
//调用executor的query方法
<E> List<E> org.apache.ibatis.executor.Executor.query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException
//实例调用子类 doQuery方法
<E> List<E> org.apache.ibatis.executor.SimpleExecutor.doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException
//通过configruation创建StatementHandler,同时对它进行拦截(第三次动态代理,调用Plugin.wrap方法,Plugin实现InvocationHandler接口),Configuration.newStatementHandler返回RoutingStatementHandler
StatementHandler org.apache.ibatis.session.Configuration.newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
//实现分页就是在这里进行扩展的(对prepare方法进行拦截),而prepare方法内,进行实例化java.sql.Statement对象

Statement org.apache.ibatis.executor.statement.StatementHandler.prepare(Connection connection, Integer transactionTimeout) throws SQLException

//为statement设置参数
void org.apache.ibatis.executor.statement.PreparedStatementHandler.parameterize(Statement statement) throws SQLException
void org.apache.ibatis.scripting.defaults.DefaultParameterHandler.setParameters(PreparedStatement ps)
void org.apache.ibatis.type.TypeHandler.setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException

//通过statementhandler进行查询
<E> List<E> org.apache.ibatis.executor.statement.SimpleStatementHandler.query(Statement statement, ResultHandler resultHandler) throws SQLException
//通过resulthandler进行结果收集
<E> Cursor<E> org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleCursorResultSets(Statement stmt) throws SQLException
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值