ShardingSphere5.1.0基于CLASS_BASED配置自定义分表算法类,实际执行过程自定义算法没有生效的问题

使用环境:

ShardingSphere5.1.0+MyBatisPlus

场景、问题:

我在application.properties中配置了自定义分片算法类,但是在实际执行中并没有生效,而是直接进行对应真实表的全子表查找

已进行操作:

application.properties分表配置项

spring.shardingsphere.rules.sharding.tables.signetrecord20220357.actual-data-nodes=current.signetrecord20220357$->{[2].collect{t → t.toString().padLeft(2,‘0’)}}0$->{0…1}
#spring.sharding.sharding.tables.signetrecord20220357.database-strategy.none.any=
spring.shardingsphere.rules.sharding.tables.signetrecord20220357.table-strategy.hint.sharding-algorithm-name=hint-sharding-algorithm
spring.shardingsphere.rules.sharding.tables.signetrecord20220357.key-generate-strategy.column=recordid
spring.shardingsphere.rules.sharding.tables.signetrecord20220357.key-generate-strategy.key-generator-name=SNOWFLAKE

spring.shardingsphere.rules.sharding.sharding-algorithms.hint-sharding-algorithm.type=CLASS_BASED
spring.shardingsphere.rules.sharding.sharding-algorithms.hint-sharding-algorithm.props.strategy=HINT
spring.shardingsphere.rules.sharding.sharding-algorithms.hint-sharding-algorithm.props.algorithmClassName=com.xuec.demo.hintstrategy.algorithm.MyHintShardingAlgorithm

自定义算法类:

@Override
public Collection<String> doSharding(Collection<String> availableTargetNames, HintShardingValue<Integer> shardingValue) {
    List<String> result = new ArrayList<>();
    Collection<Integer> values = shardingValue.getValues();

    String tableName = "signetrecord";

    for (String table : availableTargetNames) {
        for (Integer value : values) {
            tableName += value.toString();
        }

        if (table.equals(tableName)) {
            result.add(tableName);
        }
    }

    return result;
}

测试方法:

/*查询所有*/
public List<SignetRecord> findAll(){
    String tableName = "signetrecord";
    String year = "2021";
    String orgIndex = "0006";
    String month = "2";
    String resHash = "01";

    String logicTableNameSuffix = year + orgIndex;
    String logicTableName = tableName + year + orgIndex;
    String realTableName = logicTableName + month + resHash;

    RequestDataHelper.setRequestData(new HashMap<String, Object>() {{
        put(tableName, logicTableNameSuffix);
    }});

    HintManager.clear();
    HintManager hintManager = HintManager.getInstance();
    hintManager.addTableShardingValue(logicTableName, Integer.parseInt(year+orgIndex));
    hintManager.addTableShardingValue(logicTableName, Integer.parseInt(month+resHash));
    List<SignetRecord> resFindAll = signetRecordMapper.selectList(new LambdaQueryWrapper<>());

    hintManager.close();
    return resFindAll;
}

代码说明:

我利用mybatisplus拼接逻辑表名,然后再将相关的强制路由字段传入到算法类中

执行结果:

所有测试结果都是“
2022-06-10 15:05:38.926 INFO 62449 — [nio-8080-exec-1] ShardingSphere-SQL : Logic SQL: SELECT recordId,appId,requestBusinessId,encryKeyId,serialNo,signetId,signetModelId,useOrgId,userAccount,useDate,requestDate,globalSeqNo,ipAddress FROM signetRecord20210006
2022-06-10 15:05:38.926 INFO 62449 — [nio-8080-exec-1] ShardingSphere-SQL : SQLStatement: MySQLSelectStatement(table=Optional.empty, limit=Optional.empty, lock=Optional.empty, window=Optional.empty)
2022-06-10 15:05:38.926 INFO 62449 — [nio-8080-exec-1] ShardingSphere-SQL : Actual SQL: current ::: SELECT recordId,appId,requestBusinessId,encryKeyId,serialNo,signetId,signetModelId,useOrgId,userAccount,useDate,requestDate,globalSeqNo,ipAddress FROM signetrecord202100060200 UNION ALL SELECT recordId,appId,requestBusinessId,encryKeyId,serialNo,signetId,signetModelId,useOrgId,userAccount,useDate,requestDate,globalSeqNo,ipAddress FROM signetrecord202100060201
<== Columns: recordId, appId, requestBusinessId, encryKeyId, serialNo, signetId, signetModelId, useOrgId, userAccount, useDate, requestDate, globalSeqNo, ipAddress
<== Row: 1, 0044, 990000000001, S001, ABCD123457002, YZ001, YM001, 9900, TZTest, null, null, 20220317000000009000000000, 10.112.6.100
<== Row: 1, 0044, 990000000001, S001, ABCD123457001, YZ001, YM001, 9900, TZTest, null, null, 20220317000000009000000000, 10.112.6.100

问题向前推进了,我参考另一个问题


发现自己没有在META-INF中加入配置项。但是,重新启动后,报错:
由于可参考资料较少,由于错误中提示“$2”,我怀疑是配置项中逻辑表和真实表映射存在问题,但是当配置策略不生效时,是可以执行全子表查询的。

一个事实是,CLASS_BASE本身就在SPI的已知实现里,它的实现不需要在META-INF配

我最开始看了很多关于Hint策略的教程(目前多数为4.x版本,很少量使用了5.x版本),教程里的确也没有说META-INF相关的配置,但是我配置完后也的确没有按照我的实现的策略执行,处理流程更像是检索逻辑表映射的所有真实表。后来,在论坛里看到了有人提到自定义算法需要在META-INF进行配置,又根据文档中使用自定义算法的内容介绍才进行了尝试,问题的解决也有所推进。

你没有给出完整的类,如果有一个可复现问题的demo就好说明问题。master分支的example是正常通过单元测试的。

1 个赞

好的,谢谢。我再认真排查一下

京ICP备2021015875号