• sharding-sphere 单库分表实例


    生成表SQL,多张表日期累加

    fund_record20208

    fund_record20209

    fund_record20210

     
    -- ----------------------------
    -- Table structure for fund_record20208
    -- ----------------------------
    DROP TABLE IF EXISTS `fund_record20208`;
    CREATE TABLE `fund_record20208`  (
      `id` bigint(64) NOT NULL AUTO_INCREMENT,
      `user_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '用户ID',
      `amount` decimal(20, 8) NULL DEFAULT NULL COMMENT '流水金额',
      `amount_fee` decimal(20, 8) NULL DEFAULT NULL COMMENT '手续费',
      `operate` int(11) NULL DEFAULT NULL COMMENT '1用户充值,2 商城消费, 3转账支出 ',
      `order_no` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '订单编号',
      `reason` varchar(500) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '原因(充值or商品名称)',
      `create_by` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '创建用户',
      `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
      `type` tinyint(1) NULL DEFAULT NULL COMMENT '货币类型:1 RMB 2 沃金(WG) 3 元宝(DT) ',
      `symbol` varchar(2) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '收入支出符号: + (加号)  - (减号)',
      `after_balance` decimal(20, 8) NULL DEFAULT NULL COMMENT '变动后余额',
      `old_id` int(11) NULL DEFAULT NULL COMMENT '原流水Id',
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 1304357960402001923 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
    
    SET FOREIGN_KEY_CHECKS = 1;

    yaml 配置文件

    spring:
    
    
      shardingsphere:
        props:
          sql:
            #设置sql是否展示
            show: true
            check:
              table:
                metadata:
                  enabled: true
        datasource:
          #数据库名称(可以与数据库中的库名不一致)
          names: master
          master:
            type: com.alibaba.druid.pool.DruidDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://wqspro.tpddns.cn:13306/yuan_mall?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&tinyInt1isBit=false
            username: root
            password: cYyq8wtbuBO$XnpF
            # 数据库连接池的最小连接数
            initial-size: 10
            max-active: 100
            min-idle: 10
            max-wait: 60000
            pool-prepared-statements: true
            max-pool-prepared-statement-per-connection-size: 20
            time-between-eviction-runs-millis: 60000
            min-evictable-idle-time-millis: 300000
            validation-query: SELECT 1 FROM DUAL
            test-while-idle: true
            test-on-borrow: false
            test-on-return: false
            stat-view-servlet:
              enabled: true
              url-pattern: /druid/*
              #login-username: admin
              #login-password: admin
            filter:
              stat:
                log-slow-sql: true
                slow-sql-millis: 1000
                merge-sql: true
              wall:
                config:
                  multi-statement-allow: true
        sharding:
          #分库策略
          #      default-database-strategy:
          #        inline:
          #          #根据id取模决定去那个库
          #          algorithm-expression: ds$->{id % 2}
          #          sharding-column: id
          tables:
            #逻辑表名,fund_record,fund_record20209,fund_record202010,fund_record202011为实际表
            fund_record:
              actual-data-nodes: master.fund_record2020$->{8..12} #master.fund_record2019$->{11..12},
              table-strategy:
                #根据id取模决定去那个表
                #            inline:
                #              sharding-column: id
                #              algorithm-expression: user_info_$->{id % 3}
                #algorithm-expression: fund_record_2019$->{id % 3}
                standard:
                  shardingColumn: create_date
                  precise-algorithm-class-name: com.jk.mall.api.config.MyPreciseShardingAlgorithm #精确分片算法类名称,用于=和IN。。该类需实现PreciseShardingAlgorithm接口并提供无参数的构造器
                  range-algorithm-class-name: com.jk.mall.api.config.MyRangeShardingAlgorithm #范围分片算法类名称,用于BETWEEN,可选。。该类需实现RangeShardingAlgorithm接口并提供无参数的构造器
    
              key-generator:
                #id使用雪花算法
                column: id
                #雪花算法
                type: SNOWFLAKE

    自定义分片查询算法 “=”和“in”的查询

    public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Date> {
    
        /**
         * "="与"IN"进行分片的场景
         * @param collection
         * @param preciseShardingValue
         * @return
         */
        @Override
        public String doSharding(Collection<String> collection, PreciseShardingValue<Date> preciseShardingValue) {
            //对于库的分片collection存放的是所有的库的列表,这里代表flow_01~flow_12
            //配置的分片的sharding-column对应的值
            Date timeValue = preciseShardingValue.getValue();
            //分库时配置的sharding-column
            String columnName = preciseShardingValue.getColumnName();
            //需要分库的逻辑表
            String table = preciseShardingValue.getLogicTableName();
            if(StringUtils.isEmpty(timeValue)){
                throw new UnsupportedOperationException("preciseShardingValue is null");
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyM");
            //按月路由
            for (String each : collection) {
                //获取到月份
                String date  =  sdf.format(timeValue);
                if(each.endsWith(date)){
                    //这里返回回去的就是最终需要查询的表名
                    return each;
                }
            }
            return "";
        }
    #范围分片算法类名称,用于BETWEEN,"<,>"  需要注意的是 实现 RangeShardingAlgorithm接口的类型一定要与数据中表的 列名 数据类型一致
    public class MyRangeShardingAlgorithm implements RangeShardingAlgorithm<Date> {
        /**
         * BETWEEN AND进行分片的场景
         *
         * @param collection
         * @param rangeShardingValue
         * @return
         */
    
        @Override
        public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Date> rangeShardingValue) {
    
            Range<Date> valueRange = rangeShardingValue.getValueRange();
            String strDateFormat = "yyyyM";
            String yyyy = "yyyy";
            String mm = "M";
    
            SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
            SimpleDateFormat yyyySdf = new SimpleDateFormat(yyyy);
            SimpleDateFormat mmSdf = new SimpleDateFormat(mm);
    
            Date startTime = valueRange.lowerEndpoint();
            Date endTime = valueRange.upperEndpoint();
    
            List<String> month = new ArrayList<>();
            if (yyyySdf.format(startTime).equals(yyyySdf.format(endTime))) {
                //年 相等
                if (mmSdf.format(startTime).equals(mmSdf.format(endTime))) {
                    //月 相等 则不需要做任何处理
                    month.add(sdf.format(endTime));
    
                } else {
                    // 月 不相等 则将开始时间月份累加到结束时间的月份
                    Calendar forcalendar = Calendar.getInstance();
                    forcalendar.setTime(startTime);
    
                    month.add(sdf.format(forcalendar.getTime()));
                    for (int i = 0; i < 12; i++) {
                        forcalendar.add(Calendar.MONTH, 1);
                        if (mmSdf.format(forcalendar.getTime()).equals(mmSdf.format(endTime))) {
    
                            break;
                        }
                        month.add(sdf.format(forcalendar.getTime()));
                    }
                }
            } else {
                //年 不相等 将开始时间的月累加 直到与结束时间相等
                Calendar yearCalendar = Calendar.getInstance();
                yearCalendar.setTime(startTime);
    
                month.add(sdf.format(startTime));
                for (int i = 0; i < 12; i++) {
                    yearCalendar.add(Calendar.MONTH, 1);
                    if (sdf.format(yearCalendar.getTime()).equals(sdf.format(endTime))) {
                        break;
                    }
    
                    month.add(sdf.format(yearCalendar.getTime()));
                }
            }
    
    
            month.add(sdf.format(endTime));
    
    
            // 如果有固定范围则取
    //        if (valueRange.hasLowerBound()) {
    //            Date lowerEndpoint = valueRange.lowerEndpoint();
    //            leftDate = sdf.format(lowerEndpoint);
    //
    //        }
    //        if (valueRange.hasUpperBound()) {
    //            Date upperEndpoint = valueRange.upperEndpoint();
    //            rightDate = sdf.format(upperEndpoint);
    //
    //        }
    
            ArrayList<String> list = new ArrayList<>();
    
            for (String tableOriginName : collection) {
    
                String tableMonth = tableOriginName.replace("fund_record", "");
                if (month.contains(tableMonth)) {
    
                    list.add(tableOriginName);
                }
            }
    
            return list;
        }
    }
    shardingsphere的jdbc连接不能用springboot的 druid-spring-boot-starter ,只能用阿里的druid
        <!--mysql相关包开始-->
    <!--    <dependency>-->
    <!--      <groupId>com.alibaba</groupId>-->
    <!--      <artifactId>druid-spring-boot-starter</artifactId>-->
    <!--      <version>${druid.version}</version>-->
    <!--    </dependency>-->
    
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid</artifactId>
          <version>1.1.20</version>
        </dependency>
    
        <!--shardingsphere-->
        <dependency>
          <groupId>org.apache.shardingsphere</groupId>
          <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
          <version>4.1.1</version>
        </dependency>
        <dependency>
          <groupId>org.apache.shardingsphere</groupId>
          <artifactId>sharding-jdbc-spring-namespace</artifactId>
          <version>4.1.1</version>
        </dependency>

    官网:https://shardingsphere.apache.org/document/legacy/4.x/document/cn/overview/

  • 相关阅读:
    Vue2报错Already included file name 'xxx' differs from file name 'xxx' only in casing的解决方法
    npm init viteapp和npm init @vitejs/app的区别
    JVM配置参数
    Solr清空数据的简便方法
    Go查看和修改环境变量
    报错java.lang.IllegalStateException: WRITER的解决方法
    IDEA快速查找文件
    找不到import org.eclipse.jetty.webapp.WebAppContext的解决方法
    Go编译跨平台程序
    SpringBoot项目使用内嵌Jetty
  • 原文地址:https://www.cnblogs.com/zery/p/13803403.html
Copyright © 2020-2023  润新知