1. 背景
   
    在
    
     ShardingSphere-JDBC(5.1.1版本)读写分离示例
    
    一文中介绍了ShardingJdbc(5.1.1)的使用,但该文中方法没有使用DynamicDataSource,如果一起使用的话会出现异常(Caused by: java.lang.IllegalArgumentException: Property ‘sqlSessionFactory’ or ‘sqlSessionTemplate’ are required),如果想要一起使用或者将ShardingSphere-JDBC集成到原DynamicDataSource项目中则需要对数据源进行修改,本质上就是将shardingDataSource作为DynamicDataSource的一个数据源,将sharding的数据源交由原Dynamic管理。
   
    
    
    2. 数据源配置
   
将sharding的数据源交由原Dynamic管理
@Configuration
@AutoConfigureBefore({DynamicDataSourceAutoConfiguration.class, ShardingSphereAutoConfiguration.class})
@Slf4j
public class MrsszDataSourceConfig {
    @Autowired
    AbstractApplicationContext context;
    @Autowired
    private DynamicDataSourceProperties properties;
    @Lazy
    @Resource
    private DataSource shardingDataSource;
    @Bean
    public DynamicDataSourceProvider dynamicDataSourceProvider() {
        Map<String, DataSourceProperty> datasourceMap = properties.getDatasource();
        return new AbstractDataSourceProvider() {
            @Override
            public Map<String, DataSource> loadDataSources() {
                Map<String, DataSource> dataSourceMap = createDataSourceMap(datasourceMap);
                dataSourceMap.put("sharding-data-source", shardingDataSource);
                return dataSourceMap;
            }
        };
    }
    @Primary
    @Bean
    public DataSource dataSource() {
        DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
        dataSource.setStrict(properties.getStrict());
        dataSource.setStrategy(properties.getStrategy());
        dataSource.setP6spy(properties.getP6spy());
        dataSource.setSeata(properties.getSeata());
        String primary = "true".equals(this.context.getEnvironment().getProperty("spring.shardingsphere.enabled"))
                ? "sharding-data-source" : properties.getPrimary();
        dataSource.setPrimary(primary);
        log.info("Mrssz Datasource primary: {}", primary);
        return dataSource;
    }
}
    同时在
    
     application.yml
    
    配置文件中新增Dynamic数据源
   
spring:
  application:
    name: readwrite-splitting
  datasource:
    dynamic:
      primary: master
      datasource:
        master:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: 'jdbc:mysql://127.0.0.1:3306/rw_master?characterEncoding=utf-8&useSSL=false'
          password: ***
          type: com.zaxxer.hikari.HikariDataSource
          username: root
          hikari:
            connection-timeout: 30000
            idle-timeout: 600000
            minimum-idle: 10
            maximum-pool-size: 10
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      pool-name: MrsszHikariCP
      connection-timeout: 30000
      idle-timeout: 600000
      minimum-idle: 10
      maximum-pool-size: 10
      auto-commit: true
    
    
    3. 启动测试
   
    修改配置后启动项目,能看到控制台打印日志中新增了两个数据源,一个是sharding的sharding-data-source,另一个是dynamic的master。
    
     
   
    
    
    4. 新增使用Dynamic数据源的方法
   
    后续所有改动都是基于
    
     ShardingSphere-JDBC(5.1.1版本)读写分离示例
    
    做的修改。
   
    
    
    4.1 controller层新增方法
   
    @GetMapping("/queryByMaster")
    public ReadWriteContentEntity getContentByMaster(@RequestParam int id) {
        return readWriteContentService.getContentByMaster(id);
    }
    
    
    4.2 service层新增方法
   
    public ReadWriteContentEntity getContentByMaster(int id) {
        return readWriteContentMapper.getContentByMaster(id);
    }
    
    
    4.3 dao层新增方法
   
    不改动原本的sharding相关方法,写一个新方法标注使用
    
     @DS("master")
    
    数据源,如果该读到的是主库的数据而原sharding读的还是从库的话则说明同时生效了。
   
    @DS("master")
    ReadWriteContentEntity getContentByMaster(@Param("id") int id);
    
    
    4.4 mapper层新增方法
   
    <select id="getContentByMaster" resultType="cn.mrssz.readwritesplitting.entity.ReadWriteContentEntity">
        SELECT * FROM t_content
        WHERE id = #{id}
    </select>
    
    
    4. 效果测试
   
原query方法,预期读到从库的数据,正常
    
    
    新queryByMaster方法,预期读到主库的数据,正常
   
     
   
    
    
    5 其他
   
此外,值得注意的是baomidou的DynamicDataSource和ShardingSphere都是支持多数据源的,但是DynamicDataSource的多数据源存在事务异常不能回滚的问题,DynamicDataSource的多数据源方式难以支持跨数据源事务。
 
