写在前面
Spring官方推荐约定
数据源名称:数据库逻辑名+中划线+编号 = ds-xx。eg. ds-0,ds-1,ds-2
表名称:
- 表逻辑名+下划线+编号 = table_name_xx。 比如 account_1,account_2
- 表名称必须全小写。 比如 account_1,不能写成 ACCOUNT_1
Sharding数据源配置
在项目的src/main/resources/application-ptest.properties文件中配置shardingsphere相关配置。
druid.enabled=false
# 数据源配置
spring.shardingsphere.datasource.names=ds-1,ds-2
spring.shardingsphere.sharding.default-data-source-name=ds-1
spring.shardingsphere.datasource.ds-1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds-1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds-1.url=..
spring.shardingsphere.datasource.ds-1.username=..
spring.shardingsphere.datasource.ds-1.password=..
新增强制路由
需求场景:需要将一个带有分库分表的A表里的所有行数据的部分字段同步到另一张B表。而项目中已有一个A表sharding路由策略,是通过一张专门的映射表C(id,租户信息,表名,每张表的分片键,分库编号,分表编号)来分配路由。
解决思路:由于已有的A表sharding路由策略不能指定库表,需新增一个强制的路由策略。采用新增一个逻辑表名及相应的dao层CRUD,同时物理节点指向相同的实际存储节点的方式。
1、sharding配置
# 数据表配置-强制路由
spring.shardingsphere.sharding.tables.ATableV1.actual-data-nodes=ds-$->{1..2}.ATable_$->{1..64} # 由数据源名 + 表名组成,以小数点分隔
spring.shardingsphere.sharding.tables.ATableV1.database-strategy.hint.algorithm-class-name=com.test.demo.sharding.scan.IntHintAlgorithm
spring.shardingsphere.sharding.tables.ATableV1.table-strategy.hint.algorithm-class-name=com.test.demo.sharding.scan.IntHintAlgorithm
/**
* Hint指定库表路由
*/
@Slf4j
public class IntHintAlgorithm implements HintShardingAlgorithm<Integer> {
//入参collection指的是上文xml里配置的所有节点(库ds-1,ds-2,表ATable_1...ATable_64)
//入参hintShardingValue指的是传入的HintManager里的值
@Override
public Collection<String> doSharding(Collection<String> collection, HintShardingValue<Integer> hintShardingValue) {
log.info("IntHintAlgorithm param-hintShardingValue :{},collection:{}.", JSON.toJSONString(hintShardingValue), JSON.toJSONString(collection));
List<String> shardingResult = new ArrayList<>();
for (String targetName : collection) {
String[] targetNames = targetName.split("_|-");
String suffix = targetNames[targetNames.length - 1];
if (hintShardingValue.getValues().contains(Integer.parseInt(suffix))) {
shardingResult.add(targetName);
}
}
return shardingResult;
}
}
/**
* ATableV1DO的定义,注意@TableName的值也要变成ATableV1,其他copy一份ATableDO即可
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("ATableV1")
public class ATableV1DO {
/**
* 主键id,分布式主键生成直接用mybatis-plus提供的ID_WORKER_STR
*/
@TableId(value = "id", type = IdType.ID_WORKER_STR)
private Long id;
/**
* 分片键
*/
private String shardingRouteId;
/**
* 其他字段
*/
private String otherColumns;
/**
* 创建时间
*/
@