其他分享
首页 > 其他分享> > 使用MyBatis的Spring:期望的单个匹配bean但找到2

使用MyBatis的Spring:期望的单个匹配bean但找到2

作者:互联网

我一直在使用Spring和MyBatis,它在单个数据库中运行得非常好.我在尝试添加另一个数据库时遇到了困难(见reproducible example on 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注释消除自动装配的歧义,但我不知道在哪里添加它.

你能看出我出错的地方吗?

解决方法:

如果要同时使用两个数据源并且它们不是主数据源和辅助数据源,则应通过@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");
    }
}

标签:java,spring,spring-boot-2,mybatis,spring-mybatis
来源: https://codeday.me/bug/20190628/1312181.html