簡體   English   中英

MyBatis映射器類未在Spring Boot應用程序中使用兩個數據源注冊

[英]MyBatis mapper class not registered in Spring Boot application with two datasources

我們有一個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豆看起來像

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。

首先 ,我建議根本不要將SqlSessionFactory自動連接到您的DAO中。 實際上,您可以完全擺脫DAO,並在服務層中將映射器用作spring bean。

因此,您可以執行以下操作:

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注釋掃描相同的軟件包。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM