簡體   English   中英

使用MyBatis的Spring:期望的單個匹配bean但找到2

[英]Spring with MyBatis: expected single matching bean but found 2

我一直在使用Spring和MyBatis,它在單個數據庫中運行得非常好。 我在嘗試添加另一個數據庫時遇到了困難(請參閱Github上的可重復示例 )。

我正在使用Spring Java配置(即不是XML)。 我見過的大多數示例都展示了如何使用XML實現這一點。

我有兩個數據配置類(A和B),如下所示:

@Configuration
@MapperScan("io.woolford.database.mapper")
public class DataConfigDatabaseA {

    @Bean(name="dataSourceA")
    public DataSource dataSourceA() throws SQLException {
        SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
        dataSource.setDriver(new com.mysql.jdbc.Driver());
        dataSource.setUrl("jdbc:mysql://" + dbHostA + "/" + dbDatabaseA);
        dataSource.setUsername(dbUserA);
        dataSource.setPassword(dbPasswordA);
        return dataSource;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSourceA());
        return sessionFactory.getObject();
    }
}

兩個映射器,以及一個自動裝配映射器的服務:

@Service
public class DbService {

    @Autowired
    private DbMapperA dbMapperA;

    @Autowired
    private DbMapperB dbMapperB;

    public List<Record> getDabaseARecords(){
        return dbMapperA.getDatabaseARecords();
    }

    public List<Record> getDabaseBRecords(){
        return dbMapperB.getDatabaseBRecords();
    }

}

該應用程序將無法啟動:

Error creating bean with name 'dataSourceInitializer': 
  Invocation of init method failed; nested exception is 
    org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
      No qualifying bean of type [javax.sql.DataSource] is defined: 
        expected single matching bean but found 2: dataSourceB,dataSourceA

我已經讀過可以使用@Qualifier注釋消除自動裝配的歧義,但我不知道在哪里添加它。

你能看出我出錯的地方嗎?

如果要同時使用兩個數據源並且它們不是主數據源和輔助DataSourceAutoConfiguration@EnableAutoConfiguration(excludes = {DataSourceAutoConfiguration.class})通過@SpringBootApplication注釋的應用程序上的@EnableAutoConfiguration(excludes = {DataSourceAutoConfiguration.class})禁用DataSourceAutoConfiguration 之后,您可以創建自己的SqlSessionFactory並捆綁自己的DataSource 如果您還想使用DataSourceTransactionManager ,您也應該這樣做。

在這種情況下,您還沒有禁用DataSourceAutoConfiguration ,因此Spring框架將嘗試@Autowired只有一個DataSource但是有兩個,發生錯誤。

正如我之前所說,您應該禁用DataSourceAutoConfiguration並手動配置它。

您可以按如下方式禁用數據源自動配置:

@SpringBootApplication
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
public class YourApplication implements CommandLineRunner {
    public static void main (String... args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

如果你真的想同時使用多個數據庫,我建議你手動注冊正確的bean,例如:

package xyz.cloorc.boot.mybatis;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Repository;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.sql.DataSource;

@Configuration
public class SimpleTest {

    private DataSource dsA;
    private DataSource dsB;

    @Bean(name = "dataSourceA")
    public DataSource getDataSourceA() {
        return dsA != null ? dsA : (dsA = new BasicDataSource());
    }

    @Bean(name = "dataSourceB")
    public DataSource getDataSourceB() {
        return dsB != null ? dsB : (dsB = new BasicDataSource());
    }

    @Bean(name = "sqlSessionFactoryA")
    public SqlSessionFactory getSqlSessionFactoryA() throws Exception {
        // set DataSource to dsA
        return new SqlSessionFactoryBean().getObject();
    }

    @Bean(name = "sqlSessionFactoryB")
    public SqlSessionFactory getSqlSessionFactoryB() throws Exception {
        // set DataSource to dsB
        return new SqlSessionFactoryBean().getObject();
    }
}

@Repository
public class SimpleDao extends SqlSessionDaoSupport {

    @Resource(name = "sqlSessionFactoryA")
    SqlSessionFactory factory;

    @PostConstruct
    public void init() {
        setSqlSessionFactory(factory);
    }

    @Override
    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
        super.setSqlSessionFactory(sqlSessionFactory);
    }

    public <T> T get (Object id) {
        return super.getSqlSession().selectOne("sql statement", "sql parameters");
    }
}

最后,我們將每個映射器放在自己的文件夾中:

src/main/java/io/woolford/database/mapper/a/DbMapperA.java
src/main/java/io/woolford/database/mapper/c/DbMapperB.java

然后,我們創建了兩個DataConfig類,每個類對應一個數據庫。 @MapperScan注釋解析了expected single matching bean but found 2問題。

@Configuration
@MapperScan(value = {"io.woolford.database.mapper.a"}, sqlSessionFactoryRef="sqlSessionFactoryA")
public class DataConfigDatabaseA {

有必要將@Primary注釋添加到其中一個DataConfig類中的bean中:

@Bean(name="dataSourceA")
@Primary
public DataSource dataSourceA() throws SQLException {
    ...
}

@Bean(name="sqlSessionFactoryA")
@Primary
public SqlSessionFactory sqlSessionFactoryA() throws Exception {
    ...
}

感謝所有幫助過的人。 毫無疑問,這樣做的方法不止一種。 我按照@eduardlofitskyi和@GeminiKeith的建議嘗試了@Qualifier@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) ,但這又產生了一些錯誤。

萬一它有用,我們的解決方案在這里發布: https//github.com/alexwoolford/mybatis-spring-multiple-mysql-reproducible-example

您可以使用@Qualifier注釋

問題是你在Spring容器中有兩個相同的類型bean。 當你嘗試autowire bean時,Spring無法解析哪個bean注入到字段中

@Qualifier注釋是使用限定符的主要方式。 它可以在注入點與@Autowired@Inject一起應用,以指定要注入的bean。

所以,你的DbService應該是這樣的:

    @Service
    public class DbService {

    @Autowired
    @Qualifier("dataSourceA")
    private DbMapperA dbMapperA;

    @Autowired
    @Qualifier("dataSourceB")
    private DbMapperB dbMapperB;

    public List<Record> getDabaseARecords(){
        return dbMapperA.getDatabaseARecords();
    }

    public List<Record> getDabaseBRecords(){
        return dbMapperB.getDatabaseBRecords();
    }

}

我有同樣的問題,無法啟動我的Spring Boot應用程序,並通過重命名有問題的類和處理它的所有層,奇怪的是應用程序啟動成功。

我有類UOMServiceUOMServiceImpl UOMRepositoryUOMRepositoryImpl 我將它們重命名為UomServiceUomServiceImplUomRepositoryUomRepositoryImpl ,這解決了這個問題!

暫無
暫無

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

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