当前位置: 首页 > 知识库问答 >
问题:

MyBatis mapper类未在具有两个数据源的Spring Boot应用程序中注册

邬承悦
2023-03-14

我们有一个Spring Boot应用程序,它应该通过MyBatis mappers从两个不同的数据库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豆子看起来像

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-两个数据源;否则,Spring Boot应用程序启动将导致NonuniqueBeandDefinitionException

通过这种配置,Spring Boot应用程序会成功启动,在启动期间,甚至会有信息日志打印输出,表明两个映射器类都已成功识别

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.]

我们已经和这个问题斗争了一段时间了,但是找不到解决方案。可能是@初级的使用可能与此有关,但是没有它,我们甚至无法启动应用程序。我们的研究实际上似乎表明,不同的库版本甚至可能提供不同的行为:我们的堆栈是Java1.8,Spring Boot 1.2.6,Spring 4.1.7,MyBatis 3.2.5,MyBatis-Spring 1.2.2

共有1个答案

苏彦君
2023-03-14

首先,我建议完全不要将SqlSessionFactory自动绑定到您的DAO中。事实上,您可以完全摆脱DAO,并将服务层中的映射器用作春豆。

所以你做这样的事情:

public interface Db2Mapper extends MyBatisMapper<SomeType> {

  @Override
  @Select(value = ...)
  @Options(statementType = StatementType.CALLABLE)
  @Results({...}) 
  List<SomeType> select(Map<String, Object> parameters);
}

@Service
public class Db2Service{
  @Autowired
  private Db2Mapper db2Mapper;

  //...
}

其次,将各种数据源与mybatis-Spring集成的关键是在@MapperScan注释的sqlSessionFactoryRef属性中。有了它,您可以缩小哪个SqlSessionFactory实例用于女巫@MapperScan。类似于这样:

@Configuration
@MapperScan(value = { "...mapper.mybatis.db2" }, sqlSessionFactoryRef = "db2SqlSessionFactory")
public class Db2Context {

  @Primary
  @Bean(name = "db2DataSource")
  public DataSource getDataSource() { ...

  @Primary
  @Bean(name = "db2SqlSessionFactory")
  public SqlSessionFactory getSqlSessionFactory() {...

@Configuration
@MapperScan(value = { "...mapper.mybatis.other" }, sqlSessionFactoryRef = "otherSqlSessionFactory")
public class OtherContext {

  @Bean(name = "otherDataSource")
  public DataSource getDataSource() { ...

  @Bean(name = "otherSqlSessionFactory")
  public SqlSessionFactory getSqlSessionFactory() {...

显然,您不应该使用这两个@MapperScan注释扫描相同的包。

 类似资料:
  • 该应用程序在Eureka注册后以“未知”的状态启动,并且从未更改为“启动”。如果这些标志中的任何一个被设置为false,那么应用程序启动时注册为“up”。 当两个标志都启用/true时,我看到了以下一系列日志记录: 我如何让应用程序注册为启用了这两个标志/真? bootstrap.yml

  • 这是我使用SpringBoot的第一天,我试图理解体系结构,因此我开始构建一个hello world应用程序: 在我的pom.xml中,在maven-shade-plugin下,我将mainClass声明如下: 文件目标是src/main/java/com/demo/helloworld.java,该文件中的代码是: 我错过了什么?

  • 我试图在Spring Boot(v1.2.3)应用程序中使用两个数据库连接,如文档(http://docs.spring.io/spring-boot/docs/1.2.3.RELEASE/reference/htmlsingle/#howto-two-datasources. 问题似乎是次要数据源是用主要数据源的属性构建的。 有人能指出我错过了什么吗? 应用特性:

  • 问题内容: 我有一个Appp类,它从Application扩展并在清单中调用Appp。 还有两个jar,每个作者都说在清单中将它们称为Application标记。 根据android问题中如何处理多个应用程序类,要具有从Application扩展的多个应用程序类,我们应该从另一个应用程序类扩展某个应用程序类,并在清单中调用上层类。 但就我而言,我没有资源,只有罐子。我能做什么?! 问题答案: 解决

  • 我遵循留档并创建了一些与给定示例完全相同的源代码。当我运行我的代码时,我得到了这个异常: Java语言lang.RuntimeException:驱动程序组织。mariadb。jdbc。驱动程序声称不接受jdbcUrl,jdbc:h2:mem:testdb;DB\U CLOSE\U DELAY=-1;DB\u CLOSE\u ON\u EXIT=FALSE 奇怪的是有两种东西混合在一起: h2 j

  • 是否可以创建一个没有数据源的spring-boot应用程序?在我的情况下,我只需要一个简单的REST应用程序,但似乎在启动时,有一个尝试自动初始化一个数据源 我的pom.xml是 我的应用程序.属性是 当我跑的时候