sharding-jdbc系列之按月动态分表(十二)

 

前言

sharding-jdbc默认是不支持在程序的运行过程中动态的创建表的,如果需要做到动态的按月分表,所有的表需要提前创建好哦, 比如,你可以把这两年的表全部建立好。或者另外写个程序,专门用来创建表,具体怎么做,你们自己选择,本文主要是讲,如果通过sharding-jdbc实现按月动态分表。

代码实现

设置数据源的时候,给该表设置分表规则

java代码

@Bean
    public ShardingRule shardingRule(DataSourceRule dataSourceRule){
        //具体分库分表策略
        TableRule userTableRule = TableRule.builder("t_user")
                .actualTables(Arrays.asList("t_user_00", "t_user_01"))
                .tableShardingStrategy(new TableShardingStrategy("user_id", new ModuloTableShardingAlgorithm()))
                .dataSourceRule(dataSourceRule)
                .build();
        TableRule stuTableRule = TableRule.builder("t_stu")
                .actualTables(Arrays.asList("t_stu"))
                .tableShardingStrategy(new TableShardingStrategy("id", new TestTableShardingAlgorithm()))
                .dataSourceRule(dataSourceRule)
                .build();
        // 按月动态分表
        TableRule orderTableRule = TableRule.builder("t_order").
                tableShardingStrategy(new TableShardingStrategy("createTime",
                        new SingleKeyDynamicModuloTableShardingAlgorithm("t_order_"))).
                dataSourceRule(dataSourceRule).dynamic(true).build();

        //绑定表策略,在查询时会使用主表策略计算路由的数据源,因此需要约定绑定表策略的表的规则需要一致,可以一定程度提高效率
        List<BindingTableRule> bindingTableRules = new ArrayList<BindingTableRule>();
       // bindingTableRules.add(new BindingTableRule(Arrays.asList(userTableRule,stuTableRule)));
        return ShardingRule.builder()
                .dataSourceRule(dataSourceRule)
                .tableRules(Arrays.asList(userTableRule,stuTableRule,orderTableRule))
                .bindingTableRules(bindingTableRules)
                .databaseShardingStrategy(new DatabaseShardingStrategy("id", new ModuloDatabaseShardingAlgorithm()))
                .tableShardingStrategy(new TableShardingStrategy("user_id", new ModuloTableShardingAlgorithm()))
                .build();
    }

上面截图的代码,是我的一个小例子,动态分表主要看这一段代码

// 按月动态分表
 TableRule orderTableRule = TableRule.builder("t_order").
                tableShardingStrategy(new TableShardingStrategy("createTime",
                        new SingleKeyDynamicModuloTableShardingAlgorithm("t_order_"))).
                dataSourceRule(dataSourceRule).dynamic(true).build();

逻辑表t_order , 通过createTime进行分表, 分片规则类为SingleKeyDynamicModuloTableShardingAlgorithm

PS : 这里有一个属性比较重要,dynamic设置为true表示动态分表,否则是无效的。

yaml方式

dataSource:
  db0: !!org.apache.commons.dbcp.BasicDataSource
    driverClassName: org.h2.Driver
    url: jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL
    username: sa
    password: 
    maxActive: 100
  db1: !!org.apache.commons.dbcp.BasicDataSource
    driverClassName: org.h2.Driver
    url: jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL
    username: sa
    password: 
    maxActive: 100

tables:
  config:
    dynamic: true
  t_order: 
    dynamic: true
    databaseStrategy: &db001
      shardingColumns: order_id
      algorithmClassName: com.dangdang.ddframe.rdb.sharding.config.yaml.algorithm.SingleAlgorithm
    tableStrategy: &table001
      shardingColumns: id
      algorithmExpression: t_order_${id.longValue() % 2}

  t_order_item:
    dynamic: true
    #绑定表中其余的表的策略与第一张表的策略相同
    databaseStrategy: *db001
    tableStrategy: *table001

#默认数据库分片策略
defaultDatabaseStrategy:
  shardingColumns: order_id, user_id
  algorithmExpression: t_order_${id.longValue() % 2}
defaultTableStrategy:
  shardingColumns: id, order_id
  algorithmClassName: com.dangdang.ddframe.rdb.sharding.config.yaml.algorithm.MultiAlgorithm

分片策略

@RequiredArgsConstructor
public final class SingleKeyDynamicModuloTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm<Date> {

    private final String tablePrefix;

    @Override
    public String doEqualSharding(final Collection<String> availableTargetNames, final ShardingValue<Date> shardingValue) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMM");
        return tablePrefix +formatter.format(shardingValue.getValue());
    }

    @Override
    public Collection<String> doInSharding(final Collection<String> availableTargetNames, final ShardingValue<Date> shardingValue) {
        Collection<String> result = new LinkedHashSet<>(shardingValue.getValues().size());
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMM");
        for (Date value : shardingValue.getValues()) {
            result.add(tablePrefix + formatter.format(value));
        }
        return result;
    }

    @Override
    public Collection<String> doBetweenSharding(final Collection<String> availableTargetNames, final ShardingValue<Date> shardingValue) {
        Collection<String> result = new LinkedHashSet<>();
        DateFormat sdf = new SimpleDateFormat("yyyyMM");
        Range<Date> ranges = shardingValue.getValueRange();
        Date startTime = ranges.lowerEndpoint();
        Date endTime = ranges.upperEndpoint();
        // range.lowerEndpoint() = 2018-08-01
        // range.upperEndpoint() = 2018-10-01
        // 此处应该返回  tablePrefix+201808 , tablePrefix+201809,tablePrefix+201810,
        Calendar cal = Calendar.getInstance();

        while (startTime.getTime()<=endTime.getTime()){
            result.add(tablePrefix + sdf.format(startTime));
            cal.setTime(startTime);//设置起时间
            cal.add(Calendar.MONTH,1);
            startTime = cal.getTime();
        }
        return result;
    }
}

需要DEMO的,可以私聊我。

猜你喜欢

转载自blog.csdn.net/u012394095/article/details/81705382
今日推荐