Spring未整合Mybatis和整合之后Mybatis获取的方式:
Spring没有整合Mybatis之前,获取SqlSession很简单就是
DefaultSqlSessionFactory.openSession();
Spring整合Mybatis的时候,稍复杂些:
扫描dao,注册BeanDefinition并setBeanClass=MapperFactoryBean
SqlSessionTemplate 实现了SqlSession
SqlSessionTemplate 有成员SqlSession sqlSessionProxy;
这两步包含了动态代理和静态代理 自己意会下!!!!
容器启动时
Spring调用MapperFactoryBean.getObject()来生成Dao代理MapperyProxy分成如下两步:
1、this.getSqlsession()其实返回的SqlSessionTemplate,也是SqlSession,
同时也生成了SqlSession的代理类SqlSessinonInterceptor赋值给成员
2、sqlSessionTemplate.getMapper(daoInterface);SqlSessionTemplate有Configuration对象。
Configuration.getMapper(daoInterface,sqlsessionTemplate);
new MapperProxy(sqlSessionTemplate,daoInterface)是个代理类;
这样一来dao就是MapperProxy,MapperProxy中包含SqlSessionTemplate,sqlSessionTemplate成员是另一个代理类SqlSessionInterceptor。
dao调用时
当dao被调用时MapperProxy的方法被触发,proxy缓存该dao的所有方法
execute方法的执行再次委托给了SqlSessionTemplate来执行–sqlSession的接口方法,都被静态代理使用了SqlSessionTemplate.sqlSession成员(即SqlSessionInterceptor)来调用。
后边补充下MapperMethod类的说明!!!
SqlSessionTemplate的内部类SqlSessionInterceptor拦截dao的方法,再次获取SqlSession,
这个时候的SqlSession这个时候的SqlSession是每次dao请求都会创建的,
跟上面的SqlSessionTemplate的成员SqlSession代理在启动的时候和Dao绑定的只有一次,区分开!!!
我们debug一个dao的请求栈dao.batchQueryByIds(List< Long> ids)
你就把Object result = method.invoke(sqlSession,args)–>dao.findById(Long id);
这要是不懂的话没意思了赶紧补下基本功,动态代理!!
正如我们所说的,dao.batchQueryByIds(List)进入到SqlSessionInterceptor.invoke方法。
方法getSqlSession(sqlSessionFactory,ExecutorType,ExceptionTranslator);是DefaultSqlSession获取
看上面的调用栈SqlSessionInterceptor.invoke–>
SqlSessionUtil.openSession(SqlSessionFactory,ExecutorType,xxx)–>
DefaultSqlSessionFactory.openFromDataSource(ExecutorType,null,false)
new DefaultSqlSession();
总结:
dao即MapperProxy进入到invoke方法
创建MapperMethod对象,执行execute(sqlSessiontemplate,args)方法
SqlSessionTemplate的内部类静态代理到成员SqlSession动态代理的SqlSessionInterceptor上,拦截dao方法进入invoke方法,进入到getSqlSession,最终返回DefaultSqlSession对象!
在创建SqlSession的时有几个比较重要的对象也被创建了,下面是补充!
Transaction
三个好基友,抽象工厂分别创建对应的Transaction,在Spring环境下使用的SpringTransactionFactory
既然有多个工厂,我们怎么设置使用指定的工厂?
手动指定 < transactionManager type=”JDBC” />
TransactionFactory
TransactionFactory当然就是创建Transaction
Executor
没有配置默认是SimpleType–常见默认的SimpleExecutor
我们怎才能修改默认的配置呢?
MapperMethod
在MapperProxy中创建执行的execute方法的入口
此时的SqlSession已经有了几个装备的利器!
设置了Configuration对象(所有的配置都可以获取到)
Executor
Executor有了Transaction
Transaction有了DataSource
DataSource有了Connection
method.invoke(SqlSession,args);已放行执行sqlSession.selectList
还需明确几个问题?Connection还会没有看到从哪里取出来,在哪里提交,在哪里回滚,参数怎么组装映射到指定Sql等!