我们有一个 Spring Boot 应用程序,它应该通过 MyBatis 映射器从两个不同的数据库 DB2 和 Oracle 访问存储过程
我们创建了两个 DB2 上下文类,例如用于 DB2
@Configuration
@MapperScan({ "...mapper.mybatis.db2" })
public class Db2Context {
@Primary
@Bean(name = "db2DataSource")
public DataSource getDataSource() { ...
@Primary
@Bean(name = "db2SqlSessionFactory")
public SqlSessionFactory getSqlSessionFactory() {...
MyBatis bean 看起来像
public interface Db2Mapper extends MyBatisMapper<SomeType> {
@Override
@Select(value = ...)
@Options(statementType = StatementType.CALLABLE)
@Results({...})
List<SomeType> select(Map<String, Object> parameters);
并且 SqlSessionFactory bean 被注入到具有适当资格的相应 DAO 类中,例如
@Repository
public class Db2Dao {
@Autowired
@Qualifier("db2SqlSessionFactory")
SqlSessionFactory sqlSessionFactory;
...
try(SqlSession session= sqlSessionFactory.openSession(true);) {
Db2Mapper mapper = session.getMapper(Db2Mapper.class);
resultSet = mapper.select(parameters);
对于 Oracle,我们也有相同的配置、映射器和 DAO,除了在该配置中 DataSource 和 SqlSessionFactory bean 没有使用 @Primary 注释。根据 Spring Boot 参考中的描述,这是必要的:http: //docs.spring.io/spring-boot/docs/1.2.3.RELEASE/reference/htmlsingle/#howto-two-datasources;否则,Spring Boot 应用程序启动将导致 NoUniqueBeanDefinitionException
使用此配置,Spring Boot 应用程序成功启动,并且在启动期间甚至有 INFO 日志打印输出表明两个映射器类都已成功识别
INFO BeanPostProcessorChecker : Bean 'db2Mapper' of type [class org.mybatis.spring.mapper.MapperFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO BeanPostProcessorChecker : Bean 'oracleMapper' of type [class org.mybatis.spring.mapper.MapperFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
但是,在运行时我们有一个问题。首先执行 Db2Dao,然后一切顺利,DB2 存储过程开始执行,检索到的结果通过 Db2Mapper 存储。然后是 OracleDao;但是在 Oracle SP 执行之后,收到以下异常
ERROR Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
[Request processing failed; ... Type interface com....mapper.mybatis.oracle.OracleMapper is not
known to the MapperRegistry.]
我们一直在与这个问题斗争一段时间,但找不到解决方案。可能@Primary 的使用可能与它有关,但没有它我们甚至无法启动应用程序。我们的研究实际上似乎表明不同的库版本甚至可能提供不同的行为:我们的堆栈是 Java 1.8、Spring Boot 1.2.6、Spring 4.1.7、MyBatis 3.2.5、MyBatis-Spring 1.2.2