SpringBoot整合ShardingJDBC

256 阅读1分钟

一,搭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为诸葛亮的用户:

image.png

逻辑表是user,最后路由到指定表

image.png

三,分页处理

sharedingJDBC对分页支持并不好,建议只当做路由用,用于路由键做条件查询、修改、新增、删除 分页可以单独冗余张表只存主键id,如果数据量多的情况走es分页查询,通过logstatsh或者canal中间件同步数据