sharding-jdbc5系列教程(二)自定义分片算法

20 篇文章 1 订阅
8 篇文章 1 订阅

系列文章目录

sharding-jdbc5系列教程(一)springboot配置shardingjdbc+mybatis-plus+druid+dynamic-datasource

前言,本系列教程都是基于shardingjdbc5.0+版本以上的

本片讲解如何自定义分片算法

一、实现自己分片算法类

看文档可以知道

在这里插入图片描述
分片策略有三种类型,支持 STANDARD、COMPLEX 或 HINT(不区分大小写)

这里我们选择STANDARD类型的,也就是标准分片类型

看源码现有框架中的分片算法都实现了StandardShardingAlgorithm接口,在这里插入图片描述

所以我们自己定义的类也实现这个接口,代码如下。我这里参照了框架自带的InlineShardingAlgorithm分片算法类

public class MyStandardShardingAlgorithm implements StandardShardingAlgorithm {
//    private static final String ALGORITHM_EXPRESSION_KEY = "algorithm-expression";
//    private static final String ALLOW_RANGE_QUERY_KEY = "allow-range-query-with-inline-sharding";
//    private String algorithmExpression;
//    private boolean allowRangeQuery;
//    private Properties props = new Properties();

    public MyStandardShardingAlgorithm() {
    }

    @Override
    public String doSharding(Collection collection, PreciseShardingValue shardingValue) {
/*        Closure<?> closure = this.createClosure();
        closure.setProperty(shardingValue.getColumnName(), shardingValue.getValue());
        System.out.println("-------------------------------------------------------");
        return closure.call().toString();*/
        //这里写具体的分片方法 shardingjdbcValue就是传过来的分片值,经过自己处理后返回相应的字符串即为所选片名
        return "max_temp_log_1";
    }

    @Override
    public Collection<String> doSharding(Collection availableTargetNames, RangeShardingValue rangeShardingValue) {
        return availableTargetNames;
/*        if (this.allowRangeQuery) {
            return availableTargetNames;
        } else {
            throw new UnsupportedOperationException("Since the property of `allow-range-query-with-inline-sharding` is false, inline sharding algorithm can not tackle with range query.");
        }*/
    }

/*    private Closure<?> createClosure() {
        Closure<?> result = (new InlineExpressionParser(this.algorithmExpression)).evaluateClosure().rehydrate(new Expando(), (Object)null, (Object)null);
        result.setResolveStrategy(3);
        return result;
    }*/

    @Override
    public void init() {
/*        this.algorithmExpression = this.getAlgorithmExpression();
        this.allowRangeQuery = this.isAllowRangeQuery();*/
    }

/*
    private boolean isAllowRangeQuery() {
        return Boolean.parseBoolean(this.props.getOrDefault("allow-range-query-with-inline-sharding", Boolean.FALSE.toString()).toString());
    }

    private String getAlgorithmExpression() {
        String expression = "max_temp_log_$->{equipment_id % 2}";
        Preconditions.checkNotNull(expression, "Inline sharding algorithm expression cannot be null.");
        return InlineExpressionParser.handlePlaceHolder(expression.trim());
    }
*/

    @Override
    public String getType() {
        return "CLASS_BASED";
    }
}

在这里插入图片描述

这个就是分片的核心方法,具体的方式根据需求来修改

二、配置使用自定义的算法类

修改yml

配置文件

spring: 
	shardingsphere:
	    datasource:
	      names: db0
	      db0:
	        driver-class-name: com.mysql.cj.jdbc.Driver
	        type: com.alibaba.druid.pool.DruidDataSource
	        url: jdbc:mysql://127.0.0.1:3306/nbserverdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
	        username: root
	        password: root
	        filters: stat,wall,log4j2
	        # 初始连接数
	        initialSize: 5
	        # 最小连接池数量
	        minIdle: 10
	        # 最大连接池数量
	        maxActive: 20
	        # 配置获取连接等待超时的时间
	        maxWait: 60000
	        # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
	        timeBetweenEvictionRunsMillis: 60000
	        # 配置一个连接在池中最小生存的时间,单位是毫秒
	        minEvictableIdleTimeMillis: 300000
	        # 配置一个连接在池中最大生存的时间,单位是毫秒
	        maxEvictableIdleTimeMillis: 900000
	        # 配置检测连接是否有效
	        validationQuery: SELECT 1 FROM DUAL
	        testWhileIdle: true
	        testOnBorrow: false
	        testOnReturn: false
	        webStatFilter:
	          enabled: true
	        filter:
	          stat:
	            enabled: true
	            # 慢SQL记录
	            log-slow-sql: true
	            slow-sql-millis: 1000
	            merge-sql: true
	          wall:
	            config:
	              multi-statement-allow: true
	#      db1:
	#        driver-class-name: com.mysql.cj.jdbc.Driver
	#        type: com.alibaba.druid.pool.DruidDataSource
	#        url: jdbc:mysql://192.168.3.155:30002/nbserverdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
	#        username: root
	#        password: root
	    rules:
	      # 配置分片规则
	      sharding:
	        keyGenerators:
	          snowflake:
	            type: SNOWFLAKE
	            props:
	              workerId: 123
	        tables:
	          # 配置 maxtemlog 表规则
	          max_temp_log:
	            actualDataNodes: db0.max_temp_log_$->{0..1}
	            # 配置分库策略
	#            databaseStrategy:
	#              standard:
	#                shardingColumn: equipment_id
	#                shardingAlgorithmName: auto-mod-4
	            # 配置分表策略
	            tableStrategy:
	              standard:
	                shardingColumn: equipment_id
	                shardingAlgorithmName: table-inline
	            keyGenerateStrategy:
	              column: max_temp_log_id
	              keyGeneratorName: snowflake
	        # 配置分片算法
	        bindingTables: max_temp_log
	        autoTables: # 自动分片表规则配置
	          user: # 逻辑表名称
	            actualDataSources: db0 # 数据源名称
	            shardingStrategy: # 切分策略
	              standard: # 用于单分片键的标准分片场景
	                shardingColumn: user_id # 分片列名称
	                shardingAlgorithmName: auto-mod-1 # 自动分片算法名称
	        sharding-algorithms:
	          auto-mod-4:
	            type: mod
	            props:
	              sharding-count: 1
	          auto-mod-1:
	            type: mod
	            props:
	              sharding-count: 1
	          database-inline:
	            type: INLINE
	            props:
	              algorithm-expression: db$->{equipment_id % 2}
	          table-inline:
	            type: CLASS_BASED #自定义type
	            props:
	              strategy: STANDARD #标准分片类型
	              algorithmClassName: com.haiwei.springadmin.config.MyStandardShardingAlgorithm   ##这里填写自定义类的完整包路径

在这里插入图片描述

这里就是自定义核心配置

总结

修改完成就可以自己打断点测试了

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
自定义分片算法,可以按照以下步骤操作: 1. 实现ShardingAlgorithm接口,该接口有一个方法doSharding,用于根据分片键和分片策略计算出目标数据节点。 ```java public interface ShardingAlgorithm<T extends Comparable<?>> { /** * 计算分片结果. * * @param availableTargetNames 所有的可用数据节点名称集合, 一般情况下与数据源名称相同 * @param shardingValue 分片值 * @return 分片后指向的数据节点名称,即逻辑数据源名称 */ String doSharding(Collection<String> availableTargetNames, ShardingValue<T> shardingValue); } ``` 其中,ShardingValue是分片值对象,包含分片键的值和分片算法的类型。availableTargetNames是所有可用的数据节点名称集合,一般情况下与数据源名称相同。 2. 使用自定义分片算法 在使用shardingsphere-sharding-boot-starter时,可以在application.yml中配置分片规则和自定义分片算法。假设要对user表按照年龄进行分片,并使用自定义分片算法,可以按照以下配置: ```yaml spring: shardingsphere: datasource: names: ds0, ds1 ds0: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8 username: root password: root ds1: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/test1?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8 username: root password: root sharding: tables: user: actual-data-nodes: ds$->{0..1}.user_$->{0..1} table-strategy: standard: sharding-column: age precise-algorithm-class-name: com.example.MyPreciseShardingAlgorithm range-algorithm-class-name: com.example.MyRangeShardingAlgorithm key-generator: column: id type: SNOWFLAKE ``` 其中,MyPreciseShardingAlgorithm和MyRangeShardingAlgorithm分别是自定义的精确分片算法和范围分片算法,可以在代码中实现。 需要注意的是,自定义分片算法必须实现ShardingAlgorithm接口,并在application.yml中配置算法类的全限定名。在配置中,可以通过sharding-column指定分片键,通过actual-data-nodes指定真实的数据节点。具体的配置可以根据实际情况进行调整。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值