SpringBoot + MyBatisPlus多数据源配置

背景

一季度的时候,要搞数据迁移,大家基本都用datax迁移。但是我这边业务太复杂了,纯SQL不太能支持,就选择用代码程序迁移。因为旧的数据在不同的库,就产生了要从多个数据源读数据,然后写入到2个新的数据库。之前工程的配置都是只有一个库,我就开始踩坑了。

因为是两个同学一起开发的,另一个同学选择了mybatis的dynamic-datasource中间件,但是实践下来发现,无法做事务处理。然后就采用了我的方式,自己手动配置数据源。

数据源配置

主要依赖

      <!--连接池--> 
      <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.18</version>
      </dependency>

      <!--mybatisPlus--> 
      <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.1.2</version>
      </dependency>

      <!--boot--> 
      <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.22.RELEASE</version>
      </parent>

配置

配置文件

我连了6个库,这里举例简化就写两个代表,一个mysql的,一个oracle

spring:
  datasource:
    ds01:
      driverClassName: com.mysql.jdbc.Driver
      username: ***
      password: ***
      url: jdbc:mysql://***:3306/ds01?useSSL=false&autoReconnect=true&amp;autoReconnectForPools=true&amp;characterEncoding=UTF-8&allowMultiQueries=true
      type: com.alibaba.druid.pool.DruidDataSource
      # 定义初始连接数
      initial-size: 5
      # 定义最大空闲
      max-idle: 100
      # 定义最小空闲
      min-idle: 5
      # 定义最大连接数
      max-active: 100
      # 定义最长等待时间
      max-wait: 60000
      validation-query: SELECT 1 FROM DUAL
      test-on-borrow: true
      test-on-return: true
      test-while-idle: true
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 300000
    ds02:
      username: ****
      password: ****
      url: jdbc:oracle:thin:@****:1521/ds02
      type: com.alibaba.druid.pool.DruidDataSource
      initial-size: 5
      min-idle: 5
      max-active: 100
      max-wait: 60000
      validation-query: SELECT 1 FROM DUAL
      test-on-borrow: true
      test-on-return: true
      test-while-idle: true
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 300000

配置类

每个数据源增加一个对应的配置类,由于都是相同的,只写一个示例

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = "com.***.mapper.ds01", sqlSessionTemplateRef = "ds01SqlSessionTemplate")
public class DS01DataSourceConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.ds01")
    public DataSource ds01DataSource() {
        return new DruidDataSource();
    }

    @Bean
    public SqlSessionFactory ds01SqlSessionFactory(@Qualifier("ds01DataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:/mybatis/mapper/ds01/*.xml"));
        return bean.getObject();
    }

    @Bean
    public DataSourceTransactionManager ds01TransactionManager(@Qualifier("ds01DataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

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

}

事务使用

在需要开启事务的方法上,加上@Transactional就好,只是要指定transactionManager

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, transactionManager = "ds01TransactionManager")

其他问题

BaseMapper封装的方法无法使用

【问题详细描述】提示未找到绑定的SQL,但是自定义的SQL可以正常使用

【解决】是因为有数据源的Config类,在配置文件中的配置不生效,所以需要手动配置。在设置SqlSessionFactory时,将SqlSessionFactoryBean替换为MybatisSqlSessionFactoryBean即可。

分页查询不生效

【问题详细描述】pageNum和pageSize设置的值未被使用,每次都是查全部数据

【解决】依然是配置问题。在设置SqlSessionFactory时,增加分页的配置

        // 分页插件配置
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setLimit(-1);
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setPlugins(new Interceptor[]{paginationInterceptor});

开启SQL日志

【问题详细描述】一次SQL执行耗时较长,如果不开启日志,就无法了解执行情况,看起来就行程序卡住了,什么都没做

【解决】依然是在设置SqlSessionFactory时,增加配置

        // 配置打印sql语句
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setLogImpl(StdOutImpl.class);
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setConfiguration(configuration);

优化

针对上述SqlSessionFactory的配置问题,多个数据源通用,所以可以抽出来一个公共配置的方法。如下

public class MybatisPlusConfig {


    public static SqlSessionFactory mybatisSqlSessionFactoryBean(DataSource dataSource, String resource) throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        //设置数据源
        bean.setDataSource(dataSource);
        
        // 分页插件配置
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setLimit(-1);
        bean.setPlugins(new Interceptor[]{paginationInterceptor});
        
        // 配置打印sql语句
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setLogImpl(StdOutImpl.class);
        bean.setConfiguration(configuration);

        // 配置xml文件路径
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(resource));
        return bean.getObject();
    }
}

参考

springboot + mybatis + druid + 多数据源

springboot2多数据源完整示例

mybatis plus分页total=0、不计算总数的终极解决方案!!!

springboot+mybatis-plus 两种方式打印sql语句

spring boot多数据源mybatis-plus的baseMapper的里面的方法无法使用

猜你喜欢

转载自blog.csdn.net/yxz8102/article/details/107425677