一,搭demo
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.1.1</version>
</dependency>
application如下
spring:
shardingsphere:
datasource:
names: ds0
ds0:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://127.0.0.1:3306/db
username: root
password: ENC_root
props:
sql:
show: true #选配查看sql
sharding:
tables:
user:
actual-data-nodes: ds0.user_$->{1..2} #分表范围
table-strategy:
standard:
sharding-column: user_nm #分表key
precise-algorithm-class-name: com.web.method.CustomTableShardingAlgorithm #自定义策略
我这里演示的表是user表,有user_id和user_nm两个字段,用任意字段做分片键都可以,我这里选择用user_nm CustomTableShardingAlgorithm如下:
@Component
public class CustomTableShardingAlgorithm implements PreciseShardingAlgorithm<String> {
/**
* 精确分表算法
*
* @param availableTargetNames 可用的表名集合
* @param shardingValue 分片键值
* @return 目标表名
*/
@Override
public String doSharding(Collection<String> availableTargetNames,
PreciseShardingValue<String> shardingValue) {
// 分片键值(如user_id)
String value = shardingValue.getValue();
// 计算哈希值取模,分配到不同表
int hash = Math.abs(value.hashCode()) % availableTargetNames.size();
// 从可用表名中获取目标表
return availableTargetNames.stream()
.skip(hash)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("未找到匹配的表"));
}
}
这里的 shardingValue.getValue(),获取的是分片键的值,即用户名,如果和老系统做兼容的话,这里可以引入nacos配置,指定名字返回老表,如user,其他按键分配至user_1、user_2
二,演示
查询user_nm为诸葛亮的用户:
逻辑表是user,最后路由到指定表
三,分页处理
sharedingJDBC对分页支持并不好,建议只当做路由用,用于路由键做条件查询、修改、新增、删除 分页可以单独冗余张表只存主键id,如果数据量多的情况走es分页查询,通过logstatsh或者canal中间件同步数据