解决多数据源项目启动报错:No qualifying bean of type ‘org.mybatis.spring.SqlSessionTemplate‘ available: expected

文章描述了一个在使用MyBatis-Plus和SpringBoot构建项目时遇到的问题,即启动时出现关于依赖未满足的错误,原因是由于数据源配置中的sqlSessionFactory和sqlSessionTemplate存在多个实例且未明确指定主数据源。通过在相关Bean上添加@Primary注解,最终解决了冲突并成功启动项目。
摘要由CSDN通过智能技术生成

背景: mybatis-plus + 多数据源启动项目一直报错:

2024-02-22 14:31:20,298-WARN-[AbstractApplicationContext.java:591]-[main]-Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'accountController': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'baseMapper'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'IUserDAO' defined in file [D:\Epson\vipwp-springboot2\target\classes\com\epson\vipwp\dao\IUserDAO.class]: Unsatisfied dependency expressed through bean property 'sqlSessionTemplate'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.mybatis.spring.SqlSessionTemplate' available: expected single matching bean but found 4: sqlSessionTemplate,sqlSessionTemplatePop,sqlSessionTemplateOqc,sqlSessionTemplateQpost
2024-02-22 14:31:20,303-INFO-[DirectJDKLog.java:173]-[main]-Stopping service [Tomcat]
2024-02-22 14:31:20,351-ERROR-[LoggingFailureAnalysisReporter.java:40]-[main]-

***************************
APPLICATION FAILED TO START
***************************

Description:

file [D:\Epson\vipwp-springboot2\target\classes\com\epson\vipwp\dao\IUserDAO.class] required a single bean, but 4 were found:
    - sqlSessionTemplate: defined by method 'sqlSessionTemplateAssy' in class path resource [com/epson/vipwp/core/DataSourceConfig.class]
    - sqlSessionTemplatePop: defined by method 'sqlSessionTemplatePop' in class path resource [com/epson/vipwp/core/DataSourceConfig.class]
    - sqlSessionTemplateOqc: defined by method 'sqlSessionTemplateOqc' in class path resource [com/epson/vipwp/core/DataSourceConfig.class]
    - sqlSessionTemplateQpost: defined by method 'sqlSessionTemplateQpost' in class path resource [com/epson/vipwp/core/DataSourceConfig.class]


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

也就是找到4个 sqlSessionTemplate因此mybatis plus不知道该使用哪个数据源,

网上各种找解决办法都是说在

@Bean(name = "sqlSessionFactory")的定义上面添加@Primary标签,当不在service上面使用@DS注解时就使用@Primary标签定义的默认的数据源,但是无效,后来尝试了在
@Bean(name = "sqlSessionTemplate")的上面添加@Primary注解,居然神奇的解决了

以下是完整的4个数据源配置:

package com.xxx;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.util.Objects;

/**
 * 数据源配置类
 */
@Configuration
public class DataSourceConfig {
//以下四个DataSource不能定义在这,否则将循环引用,springboot无法启动
//  @Autowired  private DataSource dataSourceAssy; // 装配ASSY数据源  ---//省略后面几个,反正也不能定义
//貌似后面3个SqlSessionFactory根本没有被用到,因此注释掉

    // 定义ASSY数据源相关的Bean
    // 使用@Primary注解表示当存在多个同类型的Bean时,优先选择该Bean
    @Primary
    @Bean(name = "dataSourceAssy")
    @ConfigurationProperties(prefix = "spring.datasource.assy")
    public DataSource dataSourceAssy() {
        return DataSourceBuilder.create().build();
    } // 使用DataSourceBuilder创建数据源
    @Primary // 指定为默认jdbcTemplateAssy
    @Bean(name = "jdbcTemplateAssy")
    public JdbcTemplate jdbcTemplateAssy(@Qualifier("dataSourceAssy") DataSource dataSource) {
        return new JdbcTemplate(dataSource); // 创建JdbcTemplate实例,用于执行SQL操作
    }
    @Primary // 指定为默认SqlSessionFactory
    @Bean(name = "sqlSessionFactory") //默认数据源不能乱起名字,必须叫sqlSessionFactory
    public SqlSessionFactory sqlSessionFactoryAssy(@Qualifier("dataSourceAssy") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();// 创建SqlSessionFactoryBean实例
        factory.setDataSource(dataSource);// 设置数据源
        // 加载mybatis的相关配置文件,如果有的话
        // factoryBean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
        // 设置实体类别名包扫描
        factory.setTypeAliasesPackage("com.epson.vipwp.domain");
        // 添加 SqlSessionTemplate Bean 的定义
        SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(Objects.requireNonNull(factory.getObject()));
        return factory.getObject();// 返回SqlSessionFactory实例,用于创建SqlSession,使用SqlSession调用sql时不需要指定数据源,因为就在此处指定了
    }
    //如果要将 SqlSessionTemplate 作为单独的 Bean 注入,可以这样:
     @Primary
     @Bean(name = "sqlSessionTemplate")
     public SqlSessionTemplate sqlSessionTemplateAssy(SqlSessionFactory sqlSessionFactoryAssy) {
         return new SqlSessionTemplate(sqlSessionFactoryAssy);
     }

    //POP
    @Bean(name = "dataSourcePop")
    @ConfigurationProperties(prefix = "spring.datasource.pop")
    public DataSource dataSourcePop() {
        return DataSourceBuilder.create().build();
    }// 使用DataSourceBuilder创建POP数据源
    @Bean(name = "jdbcTemplatePop")
    public JdbcTemplate jdbcTemplatePop(@Qualifier("dataSourcePop") DataSource dataSource) {
        return new JdbcTemplate(dataSource);// 创建POP JdbcTemplate实例,用于执行SQL操作
    }

    @Bean(name = "sqlSessionFactoryPop")
    public SqlSessionFactory sqlSessionFactoryPop(@Qualifier("dataSourcePop") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();// 创建SqlSessionFactoryBean实例
        factory.setDataSource(dataSource);// 设置数据源
        factory.setTypeAliasesPackage("com.epson.vipwp.domain");
        // 添加 SqlSessionTemplate Bean 的定义
        SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(Objects.requireNonNull(factory.getObject()));
        return factory.getObject();// 返回SqlSessionFactory实例,用于创建SqlSession,使用SqlSession调用sql时不需要指定数据源,因为就在此处指定了
    }
    //如果要将 SqlSessionTemplate 作为单独的 Bean 注入,可以这样:
    @Bean(name = "sqlSessionTemplatePop")
    public SqlSessionTemplate sqlSessionTemplatePop(SqlSessionFactory sqlSessionFactoryPop) {
        return new SqlSessionTemplate(sqlSessionFactoryPop);
    }

    //OQC
    @Bean(name = "dataSourceOqc")
    @ConfigurationProperties(prefix = "spring.datasource.oqc")
    public DataSource dataSourceOqc() {
        return DataSourceBuilder.create().build();
    }
    @Bean(name = "jdbcTemplateOqc")
    public JdbcTemplate jdbcTemplateOqc(@Qualifier("dataSourceOqc") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    @Bean(name = "sqlSessionFactoryOqc")
    public SqlSessionFactory sqlSessionFactoryOqc(@Qualifier("dataSourceOqc") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();// 创建SqlSessionFactoryBean实例
        factory.setDataSource(dataSource);// 设置数据源
        factory.setTypeAliasesPackage("com.epson.vipwp.domain");
        // 添加 SqlSessionTemplate Bean 的定义
        SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(Objects.requireNonNull(factory.getObject()));
        return factory.getObject();// 返回SqlSessionFactory实例,用于创建SqlSession,使用SqlSession调用sql时不需要指定数据源,因为就在此处指定了
    }
    //如果要将 SqlSessionTemplate 作为单独的 Bean 注入,可以这样:
    @Bean(name = "sqlSessionTemplateOqc")
    public SqlSessionTemplate sqlSessionTemplateOqc(SqlSessionFactory sqlSessionFactoryOqc) {
        return new SqlSessionTemplate(sqlSessionFactoryOqc);
    }

    //qpost
    @Bean(name = "dataSourceQpost")
    @ConfigurationProperties(prefix = "spring.datasource.qpost")
    public DataSource dataSourceQpost() {
        return DataSourceBuilder.create().build();
    }
    @Bean(name = "jdbcTemplateQpost")
    public JdbcTemplate jdbcTemplateQpost(@Qualifier("dataSourceQpost") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
    @Bean(name = "sqlSessionFactoryQpost")
    public SqlSessionFactory sqlSessionFactoryQpost(@Qualifier("dataSourceQpost") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();// 创建SqlSessionFactoryBean实例
        factory.setDataSource(dataSource);// 设置数据源
        factory.setTypeAliasesPackage("com.epson.vipwp.domain");
        // 添加 SqlSessionTemplate Bean 的定义
        SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(Objects.requireNonNull(factory.getObject()));
        return factory.getObject();// 返回SqlSessionFactory实例,用于创建SqlSession,使用SqlSession调用sql时不需要指定数据源,因为就在此处指定了
    }
    //如果要将 SqlSessionTemplate 作为单独的 Bean 注入,可以这样:
    @Bean(name = "sqlSessionTemplateQpost")
    public SqlSessionTemplate sqlSessionTemplateQpost(SqlSessionFactory sqlSessionFactoryQpost) {
        return new SqlSessionTemplate(sqlSessionFactoryQpost);
    }

}

如果要使用jdbcTemplate,那么也需要在4个中添加@Primary,否则也会报错,不然就是使用哪个jdbc指明才行

  • 20
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

往事不堪回首..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值