我们使用 Mybatis 开发了一个数据持久化框架。该框架使用普通的 MyBatis API。(我们被禁止使用任何mybatis-spring,不要问……为什么?)现在我们必须将这个持久化框架与其他团队开发的另一个框架集成。这个其他框架大量使用弹簧事务处理所有事情。我们的持久化框架 DAO 将被这个框架在它自己的 API 中使用……这意味着 Spring 管理的事务将被传播到 MyBatis DAO。预计我们基于 MyBatis 的持久化框架应该毫无问题地参与 Spring 托管事务。
我们有两个选择来完成这项工作(1)将我们的持久化框架更改为使用 mybatis-spring 模块。将 DAO 更改为使用使用 spring 和 spring 的 SqlSessionFactoryBean 直接注入的映射器。我确实构建了一个模拟框架的小示例,并且一切正常,没有任何问题。问题在于这种方法需要更改几乎所有 DAO 以使用 spring 注入映射器,再次广泛测试框架。由于交货时间表,我们根本没有时间。
(2)使用mybatis-spring,使用spring定义SqlSeeionFactory——设置其他框架使用的数据源和事务管理器。就像是
<bean id="smpDataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
<property name="connectionCachingEnabled" value="true" />
<property name="URL"> <value>${db.thin.url}</value></property>
<property name="user"> <value>${db.user}</value></property>
<property name="password"><value>${db.password}</value>
</property>
</bean>
<bean id="dbTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="smpDataSource" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="smpDataSource" />
<property name="typeAliasesPackage" value="spike.smp51.domain" />
<property name="mapperLocations" value="classpath*:spike/smp51/mappers/*.xml" </bean>
然后在应用程序代码中 MyBatis DAO 从 spring 中获取 sqlseesionfactory
public static SqlSessionFactory getSqlSessionFactory() throws Exception
{
DefaultSqlSessionFactory sessionFactory = (DefaultSqlSessionFactory)ctx.getBean("sqlSessionFactory");
return sessionFactory;
}
所有 DAO 都已经使用 SqlSeesionFactory 来打开和关闭会话。把那个mybatis created sqlseeionfactory替换成spring created sqlseeionfactory就行了。这样,我们将只有几行更改。这里概述了这种方法 http://mybatis.github.io/spring/using-api.html mybatis 文档警告了这种方法——特别是它不会参与 spring 事务。
当我尝试第二种方法时,我们的框架能够参与 Spring 事务。这很奇怪。那么 MyBatis 文档不正确吗?我确实通过使用 spring transactions + AOP 创建各种事务边界来广泛验证它。MyBatis DAO 每次都能够参与 Spring 托管事务。由于第二种方法将为我们节省 90% 的开发时间——我们真的很喜欢使用它——但担心因为 MyBatis 警告遵循这种方法。有没有人尝试过这种方法?非常感谢任何反馈。