当前位置: 代码迷 >> 综合 >> SpringBoot + MyBatisPlus多数据源配置
  详细解决方案

SpringBoot + MyBatisPlus多数据源配置

热度:11   发布时间:2024-01-29 20:14:42.0

背景

一季度的时候,要搞数据迁移,大家基本都用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.Driverusername: ***password: ***url: jdbc:mysql://***:3306/ds01?useSSL=false&autoReconnect=true&amp;autoReconnectForPools=true&amp;characterEncoding=UTF-8&allowMultiQueries=truetype: com.alibaba.druid.pool.DruidDataSource# 定义初始连接数initial-size: 5# 定义最大空闲max-idle: 100# 定义最小空闲min-idle: 5# 定义最大连接数max-active: 100# 定义最长等待时间max-wait: 60000validation-query: SELECT 1 FROM DUALtest-on-borrow: truetest-on-return: truetest-while-idle: truetime-between-eviction-runs-millis: 60000min-evictable-idle-time-millis: 300000ds02:username: ****password: ****url: jdbc:oracle:thin:@****:1521/ds02type: com.alibaba.druid.pool.DruidDataSourceinitial-size: 5min-idle: 5max-active: 100max-wait: 60000validation-query: SELECT 1 FROM DUALtest-on-borrow: truetest-on-return: truetest-while-idle: truetime-between-eviction-runs-millis: 60000min-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();}@Beanpublic 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();}@Beanpublic DataSourceTransactionManager ds01TransactionManager(@Qualifier("ds01DataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}@Beanpublic 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的里面的方法无法使用