Spring Boot多数据源配置详解及报错问题解决

Spring Boot多数据源配置详解
前几天,公司提了个需求,对一个项目进行二次开发,在开发过程中,需要配置多数据源来进行数据库的操作。下面我将主键探索总结的配置流程和遇到的各种坑做以总结,希望能够帮到遇到同样问题的友友。有错的地方,请各位大佬留言指出。
1.双数据源配置
首先是数据源配置:application.yml文件,这里要注意的是单数据源下的数据库路径为url,多数据源下为jdbc-url

spring:
#单数据源
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    jdbc-url: jdbc:mysql://127.0.0.1:3306/meeting?serverTimezone=UTC
    username: root
    password: 1111


# 多数据源
  datasource:
    one: #数据源1的配置
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: jdbc:mysql://127.0.0.1:3306/meeting?serverTimezone=UTC
      username: root
      password: 1111
    two:  #数据源2的配置
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: jdbc:mysql://127.0.0.1:3306/xin-master?serverTimezone=UTC
      username: root
      password: 1111

注意点:当我们使用多数据源配置的时候,mybatis和plus的配置就不需要在.yml文件中配置了,下面就是关于数据源的一些其他config配置了。
2.当数据源配置好之后,就需要注意我们的项目结构了,由于是两套数据源,所以对应的mapper和xml文件应当放在不同的包或者目录下
在这里插入图片描述
将每个数据源对应的mapper接口,和*Mapper.xml文件分开放在不同的包下,保证在进行数据库的装配时,根据我们的不同包,对应好不同的数据源。
3.对不同的数据源进行不同的配置
数据源在配置时候要有主从之分,这里我的one数据源为主库,他的配置如下,代码过程请仔细看,主库和从库配置略有不同


> “主库配置如下”


@Configuration
> 这里进行mapper接口路径的扫描
@MapperScan(basePackages = "com.sbp.api.mapper.mapper1", sqlSessionTemplateRef = "db1SqlSessionTemplate")
public class DataSourceOneConfig {

> 这里是一个不同点,主库要加"@Primary"注解
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.one")
    @Primary
    public DataSource db1DataSource() {
        return DataSourceBuilder.create().build();
    }
> 这里是一个不同点,主库要加"@Primary"注解
    @Bean
    @Primary
    @Lazy  //这个是懒加载的注解,根据自己项目需要看是否添加 
    public SqlSessionFactory db1SqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //开启驼峰
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setMapUnderscoreToCamelCase(true);
        bean.setConfiguration(configuration);
        > "这个方法的调用是指定当前数据源的mybatis的Xml文件的路径"
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapping/mapper1/*.xml"));
        return bean.getObject();
    }

    @Bean
    @Primary
    public DataSourceTransactionManager db1TransactionManager(@Qualifier("db1DataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    @Primary
    @Lazy
    public SqlSessionTemplate db1SqlSessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

从库配置如下


和主库配置基本相同,只不过主库的每个Bean前要加"@Primary"注解,从库不加。

@Configuration
@MapperScan(basePackages = "com.sbp.api.mapper.mapper2", sqlSessionTemplateRef = "sqlSessionTemplate2")
public class DataSourceTwoConfig {
    @Bean(name = "dataSource2")
    @ConfigurationProperties(prefix = "spring.datasource.two")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "sqlSessionFactory2")
    public SqlSessionFactory db1SqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //开启驼峰
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setMapUnderscoreToCamelCase(true);
        bean.setConfiguration(configuration);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapping/mapper2/*.xml"));
        return bean.getObject();
    }

    @Bean(name = "transactionManager2")
    public DataSourceTransactionManager transactionManager(@Qualifier("dataSource2") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "sqlSessionTemplate2")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory2") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

将上面的内容配置好之后,基本就完成了双数据源的配置,但是为了项目的健康运行,还需要检查下面的一些配置:
1.项目主启动类是否添加了@MapperScan(“*”)注解,如果添加了,请将他去掉,因为我们的每个数据源在config配置类中都单独指定了basePackages 扫描路径。这里再添加上可能会报错。因为我再测试过程中遇到了。

2.项目启动后主库访问可能没有问题,但是从库访问报:Invalid bound statement (not found):com…selectAll这种错误

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.hnchances.api.mapper.mapper2.ymssm.YmSsmMapper.insterPhone

网上解决办法我找着都试了一遍,好多大佬都有遇到这种问题,提供的问题解决思路如下
通常导致这种原因的大致有以下这几种情况
1、mapper的namespace 有问题
2、 xxMapper的方法在xxMapper.xml中没有,调用那个方法就报错
3、没有正确配置ResultMap,或者只配置ResultType!等等。
当筛选完毕上边这些配置都没有问题,那么就要考虑是不是mybatis或者mybatis-plus自动加载了mapper,导致我们再配置类中手动配置的xml路径失效,导致的 Invalid bound statement (not found)问题。
需要将二者的自动加载排除:在主启动类中进行排除即可:

> "这里@SpringBootApplication中的语句就是排除二者的自动mapper加载,如果你的项目中只有其中一个依赖的话,就只需要排除一个就行,"
> "我的项目在之前开发时,他们两个mybatis持久层框架都使用了,所以两个都需要排除"
@SpringBootApplication(exclude = {MybatisAutoConfiguration.class, MybatisPlusAutoConfiguration.class})
// 开启定时任务
@EnableScheduling
//@MapperScan("com.hnchances.api.mapper")  //多数据源,这里不需要包扫描
@Import({DataSourceOneConfig.class, DataSourceTwoConfig.class})
public class ApiApplication {

    public static void main(String[] args) {
        SpringApplication.run(ApiApplication.class, args);
    }
}

至此,spring boot多数据源配置和遇坑报错问题基本都解决了,如果友友们还遇到其他问题,并且找到了解决思路的话,欢迎留下文章链接供大家参考。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
MyBatis是一个支持多数据源配置的Java持久层框架。在MyBatis配置文件中,可以通过配置多个数据源来实现多数据源配置。 首先,在配置文件中定义多个数据源。可以使用<dataSource>标签定义每个数据源的配置信息,包括数据库的驱动类名、连接地址、用户名、密码等信息。 然后,在配置文件中通过<environments>标签来配置多数据源。可以使用<environment>标签定义每个环境,包括指定数据源的ID和对应的事务管理器。 接着,在配置文件中使用<mapper>标签来指定每个数据源对应的Mapper文件。可以在<mapper>标签的namespace属性中指定Mapper文件的命名空间。 最后,在代码中通过SqlSessionFactoryBuilder来创建SqlSessionFactory,并在创建SqlSession时指定要使用的数据源的ID。可以使用SqlSessionFactory的openSession方法来创建SqlSession,并在参数中指定要使用的数据源的ID。 总结起来,使用MyBatis实现多数据源配置的步骤如下: 1. 在配置文件中定义多个数据源的配置信息。 2. 配置多数据源环境。 3. 指定每个数据源对应的Mapper文件。 4. 在代码中创建SqlSessionFactory,并指定要使用的数据源的ID。 5. 使用SqlSessionFactory创建SqlSession,并在参数中指定要使用的数据源的ID。 通过以上的配置,就可以实现在一个应用中使用多个数据源。在实际应用中,可以根据需要配置多个数据源,例如主从库读写分离、分库分表等场景。同时,可以根据需要在代码中动态切换数据源,实现更灵活的数据访问控制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值