美文网首页already
shardindjdbc-complex策略

shardindjdbc-complex策略

作者: 念䋛 | 来源:发表于2022-09-12 20:49 被阅读0次

    支持多分片键的复杂分片策略。
    配置参数:complex.sharding-columns 分片键(多个);
    complex.algorithm-class-name 分片算法实现类。
    sql和源码
    https://gitee.com/zhangjijige/shardingjdbc.git
    配置

    spring:
      main:
        allow-bean-definition-overriding: true
      shardingsphere:
        # 参数配置,显示 sql
        props:
          sql:
            show: true
        # 配置数据源
        datasource:
          # 数据源别名
          names: db0, db1, db2, db3
          # db1数据源信息
          db0:
            type: com.alibaba.druid.pool.DruidDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://127.0.0.1:3306/order_db_0?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
            username: root
            password: root
          db1:
            type: com.alibaba.druid.pool.DruidDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://127.0.0.1:3306/order_db_1?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
            username: root
            password: root
          db2:
            type: com.alibaba.druid.pool.DruidDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://127.0.0.1:3306/order_db_2?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
            username: root
            password: root
          db3:
            type: com.alibaba.druid.pool.DruidDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://127.0.0.1:3306/order_db_3?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
            username: root
            password: root
        sharding:
          tables:
            # 逻辑表名
            tbl_order:
              # 指定数据节点
              actual-data-nodes: db$->{0..3}.tbl_order_$->{0..3}
              # 分库策略
              database-strategy:
                standard:
                  sharding-column: user_id
                  precise-algorithm-class-name: com.example.shardingjdbc.sharding.algorithm.DBPreciseShardingAlgorithm
              # 分表策略
              table-strategy:
                complex:
                  sharding-columns: order_id,user_id
                  # 复合分表分片配置类
                  algorithm-class-name: com.example.shardingjdbc.sharding.algorithm.MyComplexShardingAlgorithm
    mybatis:
      mapper-locations: classpath:mapper/*.xml
    

    策略类

    public class MyComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {
        private final static String ORDER_ID = "order_id";
        private final static String USER_ID = "user_id";
    
        @Override
        public Collection<String> doSharding(Collection<String> availableTargetNames,
                                             ComplexKeysShardingValue<Long> shardingValue) {
    
            Collection<Long> orderIds = getShardingValue(shardingValue, ORDER_ID);
            Collection<Long> userIds = getShardingValue(shardingValue, USER_ID);
    
            Set<String> tables = new HashSet<>();
            for (Long userId : userIds) {
                for (Long orderId : orderIds) {
                    int index = getIndex(userId, orderId, availableTargetNames);
                    for (String tableName: availableTargetNames) {
                        if (tableName.endsWith(String.valueOf(index))) {
                            tables.add(tableName);
                        }
                    }
                }
            }
    
            return tables;
        }
    
        private Collection<Long> getShardingValue(ComplexKeysShardingValue shardingValue, String key) {
            Collection<Long> valueList = new ArrayList<>();
            Map<String, Collection<Long>> columnNameAndShardingValuesMap =
                    shardingValue.getColumnNameAndShardingValuesMap();
            if (columnNameAndShardingValuesMap.containsKey(key)) {
                valueList.addAll(columnNameAndShardingValuesMap.get(key));
            }
    
            return valueList;
        }
    
        private int getIndex(Long userId, Long orderId, Collection<String> availableTargetNames) {
            String userIdStr = String.valueOf(userId);
            String orderIdStr = String.valueOf(orderId);
            int sum = Integer.parseInt(userIdStr.substring(userIdStr.length() - 1)) + Integer.parseInt(orderIdStr.substring(orderIdStr.length() - 1));
            return sum % availableTargetNames.size();
        }
    }
    

    doSharding方法的入参


    image.png

    会有疑问doSharding方法中的入参shardingValue是如何获取数据的
    这个涉及到源码,主要是mybatis组装sql后,shardingjdbc会解析sql,并结合分片建获取分片建的数据,具体可以看源码方法
    org.apache.shardingsphere.core.route.router.sharding.ParsingSQLRouter#route
    方法中的
    OptimizeResult optimizeResult = OptimizeEngineFactory.newInstance(shardingRule, sqlStatement, parameters, generatedKey.orNull()).optimize();

    相关文章

      网友评论

        本文标题:shardindjdbc-complex策略

        本文链接:https://www.haomeiwen.com/subject/ixoqortx.html