Java实现多数据源的方式

87 阅读1分钟

1.利用Spring提供的类实现

1)在yml文件当中配置多数据源

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    hikari:
      url: jdbc:mysql://127.0.0.1:3306/datasource1?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false
      username: root
      password: root
      initial-size: 1
      min-idle: 1
      max-active: 20
      test-on-borrow: true
      driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      ck:
          url: jdbc:mysql://127.0.0.1:3306/datasource2?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false
          username: root
          password: root
          initial-size: 1
          min-idle: 1
          max-active: 20
          test-on-borrow: true
          driver-class-name: com.mysql.cj.jdbc.Driver
  1. 定义一个DataSourceConfig 配置类来配置两个数据源
@Configuration
@EnableTransactionManagement
@MapperScan("com.oppo.gsdp.kanban.backstage.mapper")
@Slf4j
public class DatasourceConfig {

    @Primary
    @Bean(name = "gpDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.hikari")
    public DataSource gpDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "ckDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.hikari.ck")
    public DataSource ckDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "dynamicDataSource")
    public DataSource dynamicDataSource(@Qualifier("gpDataSource") DataSource gpDataSource,
                                        @Qualifier("gpNewDataSource") DataSource gpNewDataSource,
                                        @Qualifier("ckDataSource") DataSource ckDataSource,
                                        @Qualifier("oracleDataSource") DataSource oracleDataSource,
                                        @Qualifier("starRocksDataSource") DataSource starRocksDataSource,
                                        @Qualifier("mysqlDataSource") DataSource mysqlDataSource,
                                        @Qualifier("mysqlSRDataSource") DataSource mysqlSRDataSource) {
        Map<Object, Object> targetDataSources = Maps.newHashMapWithExpectedSize(DYNAMIC_SOURCE_NUMBER);
        targetDataSources.put(DynamicDataSourceType.GP, gpDataSource);
        targetDataSources.put(DynamicDataSourceType.CK, ckDataSource);
        DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();
        dynamicRoutingDataSource.setTargetDataSources(targetDataSources);
        dynamicRoutingDataSource.setDefaultTargetDataSource(gpDataSource);
        return dynamicRoutingDataSource;
    }

    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dataSource,
                                               @Qualifier("paginationInterceptor") PaginationInterceptor paginationInterceptor,
                                               @Qualifier("mybatisConfiguration") MybatisConfiguration mybatisConfiguration,
                                               @Qualifier("optimisticLockerInterceptor") OptimisticLockerInterceptor optimisticLockerInterceptor) {
        MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setPlugins(paginationInterceptor, optimisticLockerInterceptor);
        sqlSessionFactoryBean.setConfiguration(mybatisConfiguration);
        sqlSessionFactoryBean.setMapperLocations(resolveMapperLocations());
        SqlSessionFactory sqlSessionFactory = null;
        try {
            sqlSessionFactory = sqlSessionFactoryBean.getObject();
        } catch (Exception e) {
            throw new ApplicationException("occur error when get sqlSessionFactory object");
        }
        if (null == sqlSessionFactory) {
            log.error("sqlSessionFactory is null");
            throw new ApplicationException("null == sqlSessionFactory");
        }

        return sqlSessionFactory;
    }

    @Bean
    public PlatformTransactionManager platformTransactionManager(@Qualifier("dynamicDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    private Resource[] resolveMapperLocations() {
        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
        List<String> mapperLocations = new ArrayList<>();
        mapperLocations.add("classpath:mapper/**/*.xml");
        List<Resource> resources = new ArrayList<>();

        for (String mapperLocation : mapperLocations) {
            try {
                Resource[] mappers = resourceResolver.getResources(mapperLocation);
                resources.addAll(Arrays.asList(mappers));
            } catch (IOException e) {
                log.error("get mapperLocation occur an exception : {}, the latest stacktrace : {}", e.getMessage(), e.getStackTrace()[0]);
            }
        }
        return resources.toArray(new Resource[0]);
    }
}

2、Spring自动化支持

  1. 引入pom依赖
         <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.5.0</version>
        </dependency>

2)在service层利用注解==@DS实现==


@Service
public class FriendImplService implements FriendService {

    @Autowired
    FriendMapper friendMapper;


    @Override
    @DS("slave_1")  // 从库, 如果按照下划线命名方式配置多个  , 可以指定前缀即可(组名)
    public List<Friend> list() {
        return friendMapper.list();
    }

    @Override
    @DS("master")
    public void save(Friend friend) {
        friendMapper.save(friend);
    }


    @DS("master")
    @DSTransactional
    public void saveAll(){
        // 执行多数据源的操作
    }

}

参考文档:blog.csdn.net/weixin_4635…