springboot2多数据源的配置及使用

springboot2多数据源的配置及使用

  • 参考
  • 1 说明
  • 2 分包方式
    • 配置数据源
    • mybatis-plus配置
    • Application类
    • 数据源配置类
    • 报错及解决
  • 3 注解方式
    • 配置依赖
    • 配置数据源
    • Application类
    • 使用

参考

https://blog.csdn.net/tuesdayma/article/details/81081666
https://www.cnblogs.com/ziyue7575/p/e97bcad8ed323602251ca3bd2b1a4457.html
https://blog.csdn.net/weixin_44605704/article/details/97746557

1 说明

多数据源有两种配置方式,一种为通过包名区分不同数据源,一种为通过注解获取动态数据源。

2 分包方式

配置数据源

在application.yml配置文件中配置数据源连接信息。不同数据源配置好别名,如下图,“first”和“second”为两个数据源别名。

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      first:
        url: jdbc:mysql://localhost:3306/more_data_source?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
        username: root
        password: root
        driver-class-name: com.mysql.cj.jdbc.Driver
      second:
        url: jdbc:mysql://localhost:3306/moreDataSource?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
        username: root
        password: root
        driver-class-name: com.mysql.cj.jdbc.Driver

数据库的其它配置可添加到对应数据库别名下,如下图:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      first:
        url: jdbc:mysql://localhost:3306/more_data_source?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
        username: root
        password: root
        driver-class-name: com.mysql.cj.jdbc.Driver
        # 数据库的其它配置可以在这里追加设置
        initial-size: 10
        max-active: 100
        max-pool-prepared-statement-per-connection-size: 20
        max-wait: 60000
        min-evictable-idle-time-millis: 300000
        min-idle: 10
        pool-prepared-statements: true
        # 其它配置内容这里就先省略了。。。

mybatis-plus配置

去掉“mapper-locations”配置。

mybatis-plus:
  # 启动时是否检查MyBatis XML文件是否存在
  check-config-location: true
  # MyBatis原生配置
  configuration:
    # 字段名称下划线转驼峰命名
    map-underscore-to-camel-case: true
  global-config:
    db-config:
      # 全局默认主键类型
      id-type: id_worker
      # 逻辑已删除值(默认为 1)
      logic-delete-value: 1
      # 逻辑未删除值(默认为 0)
      logic-not-delete-value: 0
  # mapper xml映射路径
#  mapper-locations: classpath*:mapper/**/*Mapper.xml

Application类

去掉“@MapperScan”注解,分包方式会根据不同包配置不同的mapper扫描路径,配置方式见下节数据源配置类。

@SpringBootApplication
//@MapperScan({"com.test.springbootplus.**.mapper"})
public class MoreDataSourceApplication {
     
    public static void main(String[] args) {
     
        SpringApplication.run(MoreDataSourceApplication .class, args);
    }
}

数据源配置类

注意不同数据源中“MapperScan”和“MapperLocations”配置不同,且需确保配置的地址正确。
第一个数据源配置类:

@Configuration
// 配置mybatis的接口类放的地方
@MapperScan(basePackages = "com.test.springbootplus.dataSource1.*.domain.mapper", sqlSessionFactoryRef = "test1SqlSessionFactory")
public class DataSourceConfig1 {
     

    @Bean(name = "test1DataSource")
    // 表示这个数据源是默认数据源
    @Primary
    // 读取application.yml中的配置参数映射成为一个对象
    @ConfigurationProperties(prefix = "spring.datasource.druid.first")
    public DruidDataSource getDateSource1() {
     
        return new DruidDataSource();
    }

    @Bean(name = "test1SqlSessionFactory")
    @Primary
    // @Qualifier表示查找Spring容器中名字为test1DataSource的对象
    public SqlSessionFactory test1SqlSessionFactory(@Qualifier("test1DataSource") DataSource datasource)
            throws Exception {
     
        MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(datasource);
        // 这里注意地址的准确性!!!
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/dataSource1/test/*Mapper.xml"));

        return sqlSessionFactoryBean.getObject();
    }

    //事务管理器
    @Bean(name = "test1TransactionManager")
    @Primary
    public DataSourceTransactionManager slaveTransactionManager() {
     
        return new DataSourceTransactionManager(getDateSource1());
    }

    @Bean("test1SqlSessionTemplate")
    @Primary
    public SqlSessionTemplate test1sqlsessiontemplate(
            @Qualifier("test1SqlSessionFactory") SqlSessionFactory sessionfactory) {
     
        return new SqlSessionTemplate(sessionfactory);
    }
}

同上配置第二个数据源配置类:

@Configuration
@MapperScan(basePackages = "com.test.springbootplus.dataSource2.*.domain.mapper", sqlSessionFactoryRef = "test2SqlSessionFactory")
public class DataSourceConfig2 {
     
    @Bean(name = "test2DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.second")
    public DruidDataSource getDateSource2() {
     
        return new DruidDataSource();
    }

    @Bean(name = "test2SqlSessionFactory")
    public SqlSessionFactory test2SqlSessionFactory(@Qualifier("test2DataSource") DataSource datasource)
            throws Exception {
     
        MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(datasource);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/dataSource2/test/*Mapper.xml"));
        return sqlSessionFactoryBean.getObject();
    }

    //事务管理器
    @Bean(name = "test2TransactionManager")
    public DataSourceTransactionManager slaveTransactionManager() {
     
        return new DataSourceTransactionManager(getDateSource2());
    }

    @Bean("test2SqlSessionTemplate")
    public SqlSessionTemplate test2sqlsessiontemplate(
            @Qualifier("test2SqlSessionFactory") SqlSessionFactory sessionfactory) {
     
        return new SqlSessionTemplate(sessionfactory);
    }
}

报错及解决

  • org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
    报错原因:
  1. 可能是mapper的xml中,namespace与项目的路径不一致导致的
  2. 数据源配置类中没有使用MybatisSqlSessionFactoryBean,用的是SqlSessionFactoryBean
@Bean(name = "test1SqlSessionFactory")
@Primary
public SqlSessionFactory firstSqlSessionFactory(@Qualifier("firstDS") DataSource dataSource) throws Exception {
     
    // 这里用的是SqlSessionFactoryBean 
    SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
    bean.setDataSource(dataSource);
    bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/dataSource1/test/*Mapper.xml"));
    return bean.getObject();
}

改为

@Bean(name = "test1SqlSessionFactory")
@Primary
public SqlSessionFactory test1SqlSessionFactory(@Qualifier("test1DataSource") DataSource datasource) throws Exception {
     
    // 改用MybatisSqlSessionFactoryBean
    MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
    sqlSessionFactoryBean.setDataSource(datasource);
    sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/dataSource1/test/*Mapper.xml"));
    return sqlSessionFactoryBean.getObject();
}
  • jdbcUrl is required with driverClassName

报错原因:此时可能使用的是springboot默认数据源Hikari,但是Hikari没有url属性,但是有一个jdbcUrl属性,在这种情况下,必须重写配置名“spring.datasource.secondary.url”为“spring.datasource.secondary.jdbc-url”。
如果并不想用默认的Hikari数据源,使用的为Druid,查看数据源配置类中DataSource的获取方式是否如下:

    @Bean(name = "test2DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.second")
    public DataSource getDateSource2() {
     
        return DataSourceBuilder.create().build();
    }

修改为:

    @Bean(name = "test2DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.second")
    public DruidDataSource getDateSource2() {
     
        return new DruidDataSource();
    }

3 注解方式

使用dynamic进行动态数据源的配置,官方文档:https://mybatis.plus/guide/dynamic-datasource.html#%E6%96%87%E6%A1%A3-documentation。

配置依赖

<dependency>
       <groupId>com.baomidou</groupId>
       <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
       <version>2.2.0</version>
 </dependency>

配置数据源

spring:
  datasource:
    # 可以先在这里配置好通用的配置,比如
    druid:
      initial-size: 10
      max-active: 100
      max-pool-prepared-statement-per-connection-size: 20
      max-wait: 60000
      min-evictable-idle-time-millis: 300000
      min-idle: 10
      pool-prepared-statements: true
      time-between-eviction-runs-millis: 60000
      validation-query: SELECT 1
      validation-query-timeout: 60000
      # 这里就先省略其它更多的配置了
    type: com.alibaba.druid.pool.DruidDataSource
    #dynamic开始多数据源配置
    dynamic:
      primary: dataSource1 #设置默认的数据源或者数据源组,默认值即为master
      strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候会抛出异常,不启动则使用默认数据源.
      datasource:
        dataSource1:
          url: jdbc:mysql://localhost:3306/more_data_source?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
          username: root
          password: root
          driver-class-name: com.mysql.cj.jdbc.Driver 
        dataSource2:
          url: jdbc:mysql://ocalhost:3306/moreDataSource?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
          username: root
          password: root
          driver-class-name: com.mysql.cj.jdbc.Driver

Application类

@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)
@MapperScan({
     "com.test.springbootplus.**.mapper"})
public class LasaBenefitPeopleApplication {
     
    public static void main(String[] args) {
     
        SpringApplication.run(LasaBenefitPeopleApplication.class, args);
    }
}

使用

使用@DS切换数据源。@DS可以注解在方法上和类上,同时存在方法注解优先于类上注解。

注解 结果
没有@DS 默认数据源
@DS(“dsName”) dsName可以为组名也可以为具体某个库的名称

你可能感兴趣的:(spring,boot)