本文介绍了spring boot使用sharding jdbc的配置方式,分享给大家,具体如下:
说明
要排除DataSourceAutoConfiguration,否则多数据源无法配置
@SpringBootApplication
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class Application {
  public static void main(String[] args) {
   SpringApplication.run(Application.class, args);
  }
 
}
配置的多个数据源交给sharding-jdbc管理,sharding-jdbc创建一个DataSource数据源提供给mybatis使用
官方文档:http://shardingjdbc.io/index_zh.html
步骤
配置多个数据源,数据源的名称最好要有一定的规则,方便配置分库的计算规则
@Bean(initMethod="init", destroyMethod="close", name="dataSource0")
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource0(){
  return new DruidDataSource();
}
@Bean(initMethod="init", destroyMethod="close", name="dataSource1")
@ConfigurationProperties(prefix = "spring.datasource2")
public DataSource dataSource1(){
  return new DruidDataSource();
}
配置数据源规则,即将多个数据源交给sharding-jdbc管理,并且可以设置默认的数据源,当表没有配置分库规则时会使用默认的数据源
@Bean
public DataSourceRule dataSourceRule(@Qualifier("dataSource0") DataSource dataSource0, 
    @Qualifier("dataSource1") DataSource dataSource1){
  Map<String, DataSource> dataSourceMap = new HashMap<>();
  dataSourceMap.put("dataSource0", dataSource0);
  dataSourceMap.put("dataSource1", dataSource1);
  return new DataSourceRule(dataSourceMap, "dataSource0");
}
配置数据源策略和表策略,具体策略需要自己实现
@Bean
public ShardingRule shardingRule(DataSourceRule dataSourceRule){
  //表策略
  TableRule orderTableRule = TableRule.builder("t_order")
      .actualTables(Arrays.asList("t_order_0", "t_order_1"))
      .tableShardingStrategy(new TableShardingStrategy("order_id", new ModuloTableShardingAlgorithm()))
      .dataSourceRule(dataSourceRule)
      .build();
  TableRule orderItemTableRule = TableRule.builder("t_order_item")
      .actualTables(Arrays.asList("t_order_item_0", "t_order_item_1"))
      .tableShardingStrategy(new TableShardingStrategy("order_id", new ModuloTableShardingAlgorithm()))
      .dataSourceRule(dataSourceRule)
      .build();
  //绑定表策略,在查询时会使用主表策略计算路由的数据源,因此需要约定绑定表策略的表的规则需要一致,可以一定程度提高效率
  List<BindingTableRule> bindingTableRules = new ArrayList<BindingTableRule>();
  bindingTableRules.add(new BindingTableRule(Arrays.asList(orderTableRule, orderItemTableRule)));
  return ShardingRule.builder()
      .dataSourceRule(dataSourceRule)
      .tableRules(Arrays.asList(orderTableRule, orderItemTableRule))
      .bindingTableRules(bindingTableRules)
      .databaseShardingStrategy(new DatabaseShardingStrategy("user_id", new ModuloDatabaseShardingAlgorithm()))
      .tableShardingStrategy(new TableShardingStrategy("order_id", new ModuloTableShardingAlgorithm()))
      .build();
}
创建sharding-jdbc的数据源DataSource,MybatisAutoConfiguration会使用此数据源
@Bean("dataSource")
public DataSource shardingDataSource(ShardingRule shardingRule){
  return ShardingDataSourceFactory.createDataSource(shardingRule);
}
需要手动配置事务管理器(原因未知)
//需要手动声明配置事务
@Bean
public DataSourceTransactionManager transactitonManager(@Qualifier("dataSource") DataSource dataSource){
  return new DataSourceTransactionManager(dataSource);
}
分库策略的简单实现,接口:DatabaseShardingAlgorithm
import java.util.Collection;
import java.util.LinkedHashSet;
import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.SingleKeyDatabaseShardingAlgorithm;
import com.google.common.collect.Range;
/**
 * Created by fuwei.deng on 2017年5月11日.
 */
public class ModuloDatabaseShardingAlgorithm implements SingleKeyDatabaseShardingAlgorithm<Long> {
  @Override
  public String doEqualSharding(Collection<String> databaseNames, ShardingValue<Long> shardingValue) {
   for (String each : databaseNames) {
      if (each.endsWith(shardingValue.getValue() % 2 + "")) {
        return each;
      }
    }
    throw new IllegalArgumentException();
  }
  
  @Override
  public Collection<String> doInSharding(Collection<String> databaseNames, ShardingValue<Long> shardingValue) {
   Collection<String> result = new LinkedHashSet<>(databaseNames.size());
    for (Long value : shardingValue.getValues()) {
      for (String tableName : databaseNames) {
        if (tableName.endsWith(value % 2 + "")) {
          result.add(tableName);
        }
      }
    }
    return result;
  }
  
  @Override
  public Collection<String> doBetweenSharding(Collection<String> databaseNames, ShardingValue<Long> shardingValue) {
   Collection<String> result = new LinkedHashSet<>(databaseNames.size());
    Range<Long> range = (Range<Long>) shardingValue.getValueRange();
    for (Long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
      for (String each : databaseNames) {
        if (each.endsWith(i % 2 + "")) {
          result.add(each);
        }
      }
    }
    return result;
  }
}
分表策略的基本实现,接口:TableShardingAlgorithm
import java.util.Collection;
import java.util.LinkedHashSet;
import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm;
import com.google.common.collect.Range;
/**
 * Created by fuwei.deng on 2017年5月11日.
 */
public class ModuloTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm<Long> {
  @Override
  public String doEqualSharding(Collection<String> tableNames, ShardingValue<Long> shardingValue) {
   for (String each : tableNames) {
      if (each.endsWith(shardingValue.getValue() % 2 + "")) {
        return each;
      }
    }
    throw new IllegalArgumentException();
  }
  
  @Override
  public Collection<String> doInSharding(Collection<String> tableNames, ShardingValue<Long> shardingValue) {
   Collection<String> result = new LinkedHashSet<>(tableNames.size());
    for (Long value : shardingValue.getValues()) {
      for (String tableName : tableNames) {
        if (tableName.endsWith(value % 2 + "")) {
          result.add(tableName);
        }
      }
    }
    return result;
  }
  
  @Override
  public Collection<String> doBetweenSharding(Collection<String> tableNames, ShardingValue<Long> shardingValue) {
   Collection<String> result = new LinkedHashSet<>(tableNames.size());
    Range<Long> range = (Range<Long>) shardingValue.getValueRange();
    for (Long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
      for (String each : tableNames) {
        if (each.endsWith(i % 2 + "")) {
          result.add(each);
        }
      }
    }
    return result;
  }
}
至此,分库分表的功能已经实现
读写分离
读写分离需在创建DataSourceRule之前加一层主从数据源的创建
// 构建读写分离数据源, 读写分离数据源实现了DataSource接口, 可直接当做数据源处理. 
// masterDataSource0, slaveDataSource00, slaveDataSource01等为使用DBCP等连接池配置的真实数据源
DataSource masterSlaveDs0 = MasterSlaveDataSourceFactory.createDataSource("ms_0", 
          masterDataSource0, slaveDataSource00, slaveDataSource01);
DataSource masterSlaveDs1 = MasterSlaveDataSourceFactory.createDataSource("ms_1", 
          masterDataSource1, slaveDataSource11, slaveDataSource11);
// 构建分库分表数据源
Map<String, DataSource> dataSourceMap = new HashMap<>(2);
dataSourceMap.put("ms_0", masterSlaveDs0);
dataSourceMap.put("ms_1", masterSlaveDs1);
// 通过ShardingDataSourceFactory继续创建ShardingDataSource
强制使用主库时
HintManager hintManager = HintManager.getInstance(); hintManager.setMasterRouteOnly(); // 继续JDBC操作
强制路由
HintManager hintManager = HintManager.getInstance();
hintManager.addDatabaseShardingValue("t_order", "user_id", 1L);
hintManager.addTableShardingValue("t_order", "order_id", order.getOrderId());
hintManager.addDatabaseShardingValue("t_order_item", "user_id", 1L);
hintManager.addTableShardingValue("t_order_item", "order_id", order.getOrderId());
事务
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎点击右下角反馈进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。