【shardingJDBC】不能根据分片列进行查询

版本:SpringBoot3.0.5 ShardingJDBC为5.2.1

假设我按照id进行分片存储,是没有问题的,但是查询的时候按照id匹配则报以下的错误,用除id以外的字段没问题

img

同理,我把分片字段改为age后,可以按照id查询,但是age也报这个错。这是什么情况

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你看下这篇博客吧, 应该有用👉 :SpringBoot集成ShardingJDBC系列【1】—— 添加依赖
  • 除此之外, 这篇博客: springboot2.x集成shardingjdbc5.1.1实现分表/分库查询中的 实现一个自定义分片算法 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    经过一段源码研究,可能是设计者为了插件化考虑,在上面SPI提供的内置分片算法规则中,提供了一个ClassBasedShardingAlgorithm这个算法,其内部根据设置property,将自定义的算法通过反射创建出来。
    在这里插入图片描述

    下面是ClassBasedShardingAlgorithm算法部分源码

    public final class ClassBasedShardingAlgorithm implements StandardShardingAlgorithm<Comparable<?>>, ComplexKeysShardingAlgorithm<Comparable<?>>, HintShardingAlgorithm<Comparable<?>> {
    
        private static final String STRATEGY_KEY = "strategy";
    
        private static final String ALGORITHM_CLASS_NAME_KEY = "algorithmClassName";
        ...
        
        @Getter
        @Setter
        private Properties props = new Properties();
    
        @Override
        public void init() {
            String strategyKey = props.getProperty(STRATEGY_KEY);
            Preconditions.checkNotNull(strategyKey, "The props `%s` cannot be null when uses class based sharding strategy.", STRATEGY_KEY);
            strategy = ClassBasedShardingAlgorithmStrategyType.valueOf(strategyKey.toUpperCase().trim());
            algorithmClassName = props.getProperty(ALGORITHM_CLASS_NAME_KEY);#读取配置中的props ,取得自定义算法类
            Preconditions.checkNotNull(algorithmClassName, "The props `%s` cannot be null when uses class based sharding strategy.", ALGORITHM_CLASS_NAME_KEY);
            createAlgorithmInstance();
        }
    
        private void createAlgorithmInstance() {
            switch (strategy) {
                case STANDARD:
                    standardShardingAlgorithm = ClassBasedShardingAlgorithmFactory.newInstance(algorithmClassName, StandardShardingAlgorithm.class, props);#就在这里反射创建实例
                    break;
                case COMPLEX:
                    complexKeysShardingAlgorithm = ClassBasedShardingAlgorithmFactory.newInstance(algorithmClassName, ComplexKeysShardingAlgorithm.class, props);
                    break;
                case HINT:
                    hintShardingAlgorithm = ClassBasedShardingAlgorithmFactory.newInstance(algorithmClassName, HintShardingAlgorithm.class, props);
                    break;
                default:
                    break;
            }
        }
    
        @Override
        public String doSharding(final Collection<String> availableTargetNames, final PreciseShardingValue<Comparable<?>> shardingValue) {
            return standardShardingAlgorithm.doSharding(availableTargetNames, shardingValue); #实际上用反射出来的实例去计算
        }
    
    

    因此改一下配置

      shardingsphere:
        mode:
          type: Memory
        datasource:
          names: master
          master:
            url: jdbc:mysql://192.168.1.55:3306/demoDb?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useAffectedRows=true&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true
            driver-class-name: com.mysql.cj.jdbc.Driver
            username: demo
            password: 12345678
            type: com.alibaba.druid.pool.DruidDataSource
        rules:
          sharding:
            binding-tables:
              - "sys_user"
            tables:
              sys_user:
                actual-data-nodes: master.sys_user_$->{0..1}
                table-strategy:
                  standard:
                    sharding-column: id
                    sharding-algorithm-name: myShardingAlgorithm  #引用算法名称
            sharding-algorithms:
              idModShardingAlgorithm:
                props:
                  sharding-count: 2
                type: MOD
              myShardingAlgorithm:   #新加的算法名称
                props:
                  strategy: standard
                  # 自定义标准分配算法
                  algorithmClassName: com.kuizii.demo.core.config.IdModShardingAlgorithm
                type: CLASS_BASED
    

    自定义一个算法

    public class IdModShardingAlgorithm implements StandardShardingAlgorithm<String> {
        @Override
        public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
            for (String s : collection) {
                 Integer mod= Integer.parseInt( preciseShardingValue.getValue())%2;
                if (s.endsWith( mod.toString())) {
                    return s;
                }
                continue;
            }
            return "sys_user";
        }
    
        @Override
        public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<String> rangeShardingValue) {
            return null;
        }
    
        @Override
        public void init() {
    
        }
    
        @Override
        public String getType() {
            return "MOD1";
        }
    }
    

    经过改造,再运行,自定义的分片算法完成了!

    相关源码查看我的

    gitee项目

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^