complex复合分片算法配置分库分表
经过上一篇 通过SPI实现range查询策略 实现了范围查询之后,那么在本文的开始之前,我在范围查询测试方法当中在加一个条件,来看看查询的结果如何,添加一个 goods_id 查询条件:
@Test
void getOrderBetween() {
QueryWrapper<Order> qw = new QueryWrapper<>();
qw.between("tid", 676006592218402816L, 676006593883541505L);
qw.eq("goods_id", 1005);
this.orderMapper.selectList(qw).forEach(System.out::println);
}
通过观察运行结果发现,对所有的库和所有的表都进行了查询,其实在我添加了 goods_id 之后是可以精确到某一个库当中的某一张表的,那么如果想要在这种情况下,实现精确的查询,那么就需要用到本文当中所介绍的复合分片算法来进行实现,那么编写套路和之前通过 SPI 扩展 stand 算法差不多。
概述
复合分片策略支持对多个分片健操作
添加配置
# 配置分表策略 主键+分片算法
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.complex.sharding-columns=tid, goods_id
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.complex.sharding-algorithm-name=complex-table
spring.shardingsphere.rules.sharding.sharding-algorithms.complex-table.type=COMPLEX_TEST_TAB
# 配置分库策略 主键+分片算法
spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.complex.sharding-columns=tid, goods_id
spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.complex.sharding-algorithm-name=complex-db
spring.shardingsphere.rules.sharding.sharding-algorithms.complex-db.type=COMPLEX_TEST_DB
创建算法实现
DbComplexShardingAlgorithm.java
/**
* @author BNTang
* @program ShardingSpherePro
* @date Created in 2021/12/17 017 15:28
* @description
**/
public class DbComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {
@Override
public Collection<String> doSharding(Collection<String> collection, ComplexKeysShardingValue<Long> complexKeysShardingValue) {
return null;
}
@Override
public void init() {
}
@Override
public String getType() {
return null;
}
}
TableComplexShardingAlgorithm.java
/**
* @author BNTang
* @program ShardingSpherePro
* @date Created in 2021/12/17 017 15:28
* @description
**/
public class TableComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {
@Override
public Collection<String> doSharding(Collection<String> collection, ComplexKeysShardingValue<Long> complexKeysShardingValue) {
return null;
}
@Override
public void init() {
}
@Override
public String getType() {
return null;
}
}
在之前我们 stand 实现的是 StandardShardingAlgorithm 那么 complex 实现的为 ComplexKeysShardingAlgorithm,然后就可以与 stand 一样在覆盖的方法当中编写你自己的算法逻辑即可,博主的算法实现逻辑如下:
DbComplexShardingAlgorithm.java
/**
* @author BNTang
* @program ShardingSpherePro
* @date Created in 2021/12/17 017 15:28
* @description
**/
public class DbComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {
@Override
public Collection<String> doSharding(Collection<String> collection,
ComplexKeysShardingValue<Long> complexKeysShardingValue) {
/*tid的范围查询
Range<Long> tidRange = complexKeysShardingValue.getColumnNameAndRangeValuesMap().get("tid");
如果是tid的范围查询,则返回对应的库名*/
Collection<Long> goodsIds = complexKeysShardingValue.getColumnNameAndShardingValuesMap().get("goods_id");
// 如果是goods_id的范围查询,则返回对应的库名
if (null != goodsIds) {
return goodsIds.stream()
.map(goodsId -> {
BigInteger num = BigInteger.valueOf(goodsId).mod(new BigInteger("2"));
num = num.add(new BigInteger("1"));
return "shardingspheredb" + num;
})
.collect(Collectors.toList());
}
return collection;
}
@Override
public void init() {
}
@Override
public String getType() {
return "COMPLEX_TEST_DB";
}
}
TableComplexShardingAlgorithm.java
/**
* @author BNTang
* @program ShardingSpherePro
* @date Created in 2021/12/17 017 15:28
* @description
**/
public class TableComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {
@Override
public Collection<String> doSharding(Collection<String> collection,
ComplexKeysShardingValue<Long> complexKeysShardingValue) {
/*
tid的范围查询
Range<Long> tidRange = complexKeysShardingValue.getColumnNameAndRangeValuesMap().get("tid");
如果是tid的范围查询,则返回对应的库名
*/
Collection<Long> goodsIds = complexKeysShardingValue.getColumnNameAndShardingValuesMap().get("goods_id");
// 如果是goods_id的范围查询,则返回对应的库名
if (null != goodsIds) {
return goodsIds.stream()
.map(goodsId -> {
BigInteger num = BigInteger.valueOf(goodsId).mod(new BigInteger("2"));
return complexKeysShardingValue.getLogicTableName() + "_" + num;
})
.collect(Collectors.toList());
}
return collection;
}
@Override
public void init() {
}
@Override
public String getType() {
return "COMPLEX_TEST_TAB";
}
}
修改 SPI 文件添加算法类的相对路径:
测试
再次运行之前的范围查询带了 goods_id 的查询,运行结果如下,发现,已经成为了精确的查询,查询的库为 shardingspheredb1 当中的 t_order_0 的真实表:
然后再将 goods_id 去掉进行查询,走的就是博主配置的全库全表如下: