Springboot MyBatis 配置多数据源和多数据库识别

本文详细记录了在Springboot项目中如何配置多数据源并实现多数据库自动识别,包括application.yml配置、数据库类型识别配置类、数据源配置以及在mapper.xml中的使用方法,为面临类似需求的开发者提供参考。

 

网上配置多数据源与多数据库的文章大多是分开的,同时考虑多数据源和多数据库的情况较少,因为项目中碰到了这种情况,特别记录下来与大家共享。

1. 配置application.yml

spring:
  datasource:
    db1:
      jdbc-url: jdbc:sqlserver://xxx.xxx.xxx.xxx:1433;DatabaseName=xxx
      username: xxx
      password: xxx
      # 使用druid数据源 ,指定其连接池
      type: com.alibaba.druid.pool.DruidDataSource
      driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
      filters: stat
      maxActive: 20
      initialSize: 1
      maxWait: 60000
      minIdle: 1
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 300000
      validationQuery: select 1
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      poolPreparedStatements: true
      maxOpenPreparedStatements: 20
    db2:
      jdbc-url: jdbc:sqlserver://xxx.xxx.xxx.xxx:1433;DatabaseName=xxx
      username: xxx
      password: xxx
      # 使用druid数据源 ,指定其连接池
      type: com.alibaba.druid.pool.DruidDataSource
      driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
      filters: stat
      maxActive: 20
      initialSize: 1
      maxWait: 60000
      minIdle: 1
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 300000
      validationQuery: select 1
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      poolPreparedStatements: true
      maxOpenPreparedStatements: 20

2. 数据库类型识别配置类

config类中配置DatabaseIdProvider

    /**
     * 自动识别使用的数据库类型
     * setProperty("数据库类型","databaseId"),在mapper.xml中databaseId的值就是跟这里对应,
     * 如果没有databaseId选择则说明该sql适用所有数据库
     * */
    @Bean
    public DatabaseIdProvider getDatabaseIdProvider(){
        DatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
        Properties properties = new Properties();
        properties.setProperty("Oracle","oracle");
        properties.setProperty("MySQL","mysql");
        properties.setProperty("DB2","db2");
        properties.setProperty("Derby","derby");
        properties.setProperty("H2","h2");
        properties.setProperty("HSQL","hsql");
        properties.setProperty("Informix","informix");
        properties.setProperty("MS-SQL","ms-sql");
        properties.setProperty("SQL Server","sqlserver");
        properties.setProperty("PostgreSQL","postgresql");
        properties.setProperty("Sybase","sybase");
        properties.setProperty("Hana","hana");
        databaseIdProvider.setProperties(properties);
        return databaseIdProvider;
    }

3. 数据源配置类

主数据源:扫描mapper文件夹,放在此文件夹下mapper文件使用db1数据源

@Configuration
@MapperScan(basePackages = "com.inetsoft.mapper", sqlSessionTemplateRef = "db1SqlSessionTemplate")
public class DataSource1Config {
    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.db1")
    public DataSource db1DataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public SqlSessionFactory db1SqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource, DatabaseIdProvider databaseIdProvider) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setDatabaseIdProvider(databaseIdProvider);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));
        return bean.getObject();
    }

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

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

从数据源:扫描mapper2文件夹,放在此文件夹下mapper文件使用db2数据源

@Configuration
@MapperScan(basePackages = "com.inetsoft.mapper2", sqlSessionTemplateRef = "db2SqlSessionTemplate")
public class DataSource2Config {
    @Bean(name = "db2DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.db2")
    public DataSource db2DataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public SqlSessionFactory db2SqlSessionFactory(@Qualifier("db2DataSource") DataSource dataSource, DatabaseIdProvider databaseIdProvider) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setDatabaseIdProvider(databaseIdProvider);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper2/*.xml"));
        return bean.getObject();
    }

    @Bean
    public DataSourceTransactionManager db2TransactionManager(@Qualifier("db2DataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    public SqlSessionTemplate db2SqlSessionTemplate(@Qualifier("db2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

 4. 在mapper.xml中使用

方法1

    <select id="queryMaxSort"  resultType="java.lang.Integer" databaseId="mysql">
        select  ifnull(max(sort_),0)+1 sort_ from sys_user
    </select>

    <select id="queryMaxSort"  resultType="java.lang.Integer" databaseId="sqlserver">
        select  isnull(max(sort_),0)+1 sort_ from sys_user
    </select>

    <select id="queryMaxSort"  resultType="java.lang.Integer" databaseId="oracle">
        select  nvl(max(sort_),0)+1 sort_ from sys_user
    </select>

方法2

<select id="queryMaxSort" parameterType="String" resultMap="SuperResultMap">
    SELECT
      <if test="_databaseId == 'mysql'">
          ifnull(max(sort_),0)+1 sort_
      </if>
      <if test="_databaseId == 'sqlserver'">
          isnull(max(sort_),0)+1 sort_
      </if>
      <if test="_databaseId == 'oracle'">
          nvl(max(sort_),0)+1 sort_
      </if>
    from sys_user
  </select>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值