【MyBatisPlus多数据源 | Seata数据源代理】SpringBoot+MyBatisPlus+Seata动态数据源代理

1.依赖

MyBatisPlus多数据源管理的依赖

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

2.yml配置

spring:
  datasource:
    datasource1:
      url: jdbc:mysql://localhost:3306/database01?rewriteBatchedStatements=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
      username: root
      password: admin
    datasource2:
      url: jdbc:mysql://localhost:3306/database02?rewriteBatchedStatements=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
      username: root
      password: admin

如有黄色警告,忽略即可。

3.DataSourceConfiguration 数据源代理配置类

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import io.seata.rm.datasource.DataSourceProxy;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
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.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.annotation.Resource;
import javax.sql.DataSource;


@Configuration
public class DataSourceConfiguration {

	@Resource
	private MetaObjectHandler metaObjectHandler;
	@Resource
	private MybatisPlusInterceptor mybatisPlusInterceptor;

	@Bean("originalDatasource1")
	@ConfigurationProperties(prefix = "spring.datasource.datasource1")
	public DataSource dataSource2() {
		return new DruidDataSource();
	}

	@Bean("originalDatasource2")
	@ConfigurationProperties(prefix = "spring.datasource.datasource2")
	public DataSource dataSource1() {
		return new DruidDataSource();
	}

	@Primary
	@Bean("datasource1")
	public DataSourceProxy dataSourceProxySatisfactory(@Qualifier("originalDatasource1") DataSource druidDataSource) {
		return new DataSourceProxy(druidDataSource);
	}

	@Bean("datasource2")
	public DataSourceProxy dataSourceProxyMysql(@Qualifier("originalDatasource2") DataSource druidDataSource) {
		return new DataSourceProxy(druidDataSource);
	}

	@Bean("dynamicDataSource")
	public DataSource dynamicDataSource(@Qualifier("datasource1") DataSourceProxy datasource1, @Qualifier("datasource2") DataSourceProxy datasource2) {
		DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();
		dynamicRoutingDataSource.addDataSource("name1", datasource1);
		dynamicRoutingDataSource.addDataSource("name2", datasource2);
		dynamicRoutingDataSource.setPrimary("name1");
		dynamicRoutingDataSource.setSeata(true);
		return dynamicRoutingDataSource;
	}

	/**
	 * 解决引入seata后@Transactional注解失效的问题
	 */
	@Bean("txManager")
	public DataSourceTransactionManager txManager(@Qualifier("dynamicDataSource") DataSource dataSource) {
		return new DataSourceTransactionManager(dataSource);
	}

	@Bean
	public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dataSource) throws Exception {
		// 这里用 MybatisSqlSessionFactoryBean 代替了 SqlSessionFactoryBean,否则 MyBatisPlus 不会生效
		MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
		mybatisSqlSessionFactoryBean.setDataSource(dataSource);
		mybatisSqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:system/mapper/xml/*Mapper.xml"));
		mybatisSqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
		// MyBatis-Plus 配置
		MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
		// MyBatis-Plus的分页、乐观锁等功能是通过MybatisPlusInterceptor插入的
		mybatisConfiguration.addInterceptor(mybatisPlusInterceptor);
		// 控制台打印日志
		mybatisConfiguration.setLogImpl(StdOutImpl.class);
		// 返回为null的字段
		mybatisConfiguration.setCallSettersOnNulls(true);
		mybatisSqlSessionFactoryBean.setConfiguration(mybatisConfiguration);
		GlobalConfig globalConfig = new GlobalConfig();
		// 字段自动填充
		globalConfig.setMetaObjectHandler(metaObjectHandler);
		GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig();
		// 主键策略
		dbConfig.setIdType(IdType.AUTO);
		// 查询策略
		dbConfig.setWhereStrategy(FieldStrategy.DEFAULT);
		// 插入策略
		dbConfig.setInsertStrategy(FieldStrategy.DEFAULT);
		// 更新策略(IGNORED表示null值也会更新)
		dbConfig.setUpdateStrategy(FieldStrategy.IGNORED);
		globalConfig.setDbConfig(dbConfig);
		mybatisSqlSessionFactoryBean.setGlobalConfig(globalConfig);
		return mybatisSqlSessionFactoryBean.getObject();
	}

}

4.切换数据源

方法一:使用 @DS 切换数据源
@DS 可以注解在方法上或类上,同时存在就近原则。方法上的注解优先于类上的注解。

/**
 * serice实现类
 */
@Service
@DS("datasource1")
public class MysqlSlowLogServiceImpl extends ServiceImpl<MysqlSlowLogMapper, MySqlSlowLog> implements MysqlSlowLogService {

	@Resource
	private MysqlSlowLogMapper mapper;

	@Override
	public Page<MySqlSlowLog> pageSlowLog(PaginationRequest<SearchSlowLogRequest, MySqlSlowLog> paginationRequest) {
		return page(paginationRequest.buildPage(), paginationRequest.buildQueryWrapper());
	}

}

方法二:用 DynamicDataSourceContextHolder.push() 手动切换数据源

    @Override
    @DS("datasource1")
    public void getCopyDataInfo(String targetTableName, Long serverId, String dbName, Long taskSetId) {
        GetCopyDataInfoVO info = getCopyDataInfoOne(targetTableName, serverId, dbName, taskSetId);
        // 手动切换数据源
        DynamicDataSourceContextHolder.push("datasource2");
        saveCopyDataInfo(info.getSyncInfo(), info.getTaskSetId(), info.getSrTableInfo(), info.getTgtTableInfo(), info.getSrColInfoList(), info.getTgtColInfoList());
    }

你可能感兴趣的:(MyBatis-Plus,java,springboot,mysql)