springboot通过sharding-dbc按年、月分片

目录

springboot通过sharding-dbc按年、月分片

1、引入pom依赖

2、application.yml配置

3、分片算法

4、注意事项


1、引入pom依赖

java 复制代码
 <!--shardingjdbc分片,和Druid不兼容,如果不使用sharding则需要注释-->
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.1.1</version>
        </dependency>

2、application.yml配置

java 复制代码
spring:
    autoconfigure:
        exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
    main:
        allow-bean-definition-overriding: true
    shardingsphere:
        #配置数据源
        datasource:
            names: ds-master
            ds-master:
                type: com.alibaba.druid.pool.DruidDataSource
                driver-class-name: com.mysql.cj.jdbc.Driver
                url: jdbc:mysql://147.1.5.229:3306/aihosp?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
                username: aihosp
                password: DF3f3#KF#83Fe
        sharding:
            tables:
                year_table:
                    actual-data-nodes: ds-master.year_table$->{2021..2025}  #按年分表
                    tableStrategy:
                        standard: #用于单分片键的标准分片场景
                            sharding-column: create_date
                            precise-algorithm-class-name: com.gxfy.common.algorithm.PreciseRangeShardingAlgorithm # 精确分片算法类名称,用于=和IN。该类需实现PreciseShardingAlgorithm接口并提供无参数的构造器
                            range-algorithm-class-name: com.gxfy.common.algorithm.PreciseRangeShardingAlgorithm #范围分片算法类名称,用于BETWEEN,可选。该类需实现RangeShardingAlgorithm接口并提供无参数的构造器
                    key-generator:
                        column: id
                        type: SNOWFLAKE #分布式全局ID(雪花算法)
                        retry-interval-milliseconds: 500
             
                month_table:
                    actual-data-nodes: ds-master.month_table$->{2022..2025}0$->{1..9},ds-master.month_table$->{2022..2025}1$->{0..2}  #按月分表
                    tableStrategy:
                        standard: #用于单分片键的标准分片场景
                            sharding-column: create_date
                            precise-algorithm-class-name: com.gxfy.common.algorithm.PreciseRangeShardingAlgorithm
                            range-algorithm-class-name: com.gxfy.common.algorithm.PreciseRangeShardingAlgorithm
                    key-generator:
                        column: id
                        type: SNOWFLAKE #分布式全局ID(雪花算法)
                        retry-interval-milliseconds: 500
     )
                        retry-interval-milliseconds: 500

        #其他运行属性
        props:
            sql:
                show: false

3、分片算法

java 复制代码
import com.google.common.collect.Range;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 *
 * 按年分片
 * 精准分库PreciseShardingDBAlgorithm
 *
 * 范围分库RangeShardingDBAlgorithm
 *
 * 精准分表PreciseShardingTableAlgorithm
 *
 * 范围分表RangeShardingTableAlgorithm:
 */
@Slf4j
public class PreciseRangeShardingAlgorithm implements PreciseShardingAlgorithm<String>,RangeShardingAlgorithm<String> {
    /**
     *  RangeShardingAlgorithm的重写  根据传入的分片健的值,对所有待选择的表中 根据自己的业务逻辑进行判断,选择符合条件的表返回
     * @param tableNameList 返回需要查询的表
     * @param shardingValue 传入的分片健的值
     * @return 返回符合条件的表名称
     */
    @Override
    public Collection<String> doSharding(Collection<String> tableNameList, RangeShardingValue<String> shardingValue) {

        System.out.println("[MyTableRangeShardingAlgorithm] shardingValue: [{}]\n"+ shardingValue);
        Set<String> tableNameResultList = new LinkedHashSet<>();
        Range<String> rangeValue = shardingValue.getValueRange();

        String flag = "year";
        for (String tableName : tableNameList) {
            if (tableName.startsWith("month_table")) {
                flag = "month";
                break;
            }

        }

        if ("year".equals(flag)) {
            int lowInt = Integer.parseInt(rangeValue.lowerEndpoint().substring(0,5).replaceAll("-",""));
            int upperInt = Integer.parseInt(rangeValue.upperEndpoint().substring(0,5).replaceAll("-",""));

            for (String tableNameItem : tableNameList) {
                String substring = tableNameItem.substring(tableNameItem.length() - 4);
                int tableItem = Integer.valueOf(substring);
                if(tableItem >=  lowInt && tableItem <= upperInt ){
                    tableNameResultList.add(tableNameItem);
                }

            }
        } else if ("month".equals(flag)) {

            int lowInt = Integer.parseInt(rangeValue.lowerEndpoint().substring(0,7).replaceAll("-",""));
            int upperInt = Integer.parseInt(rangeValue.upperEndpoint().substring(0,7).replaceAll("-",""));

            for (String tableNameItem : tableNameList) {
                String substring = tableNameItem.substring(tableNameItem.length() - 6,tableNameItem.length());
                int tableItem = Integer.valueOf(substring);
                if(tableItem >=  lowInt && tableItem <= upperInt ){
                    tableNameResultList.add(tableNameItem);
                }

            }
        }


        return tableNameResultList;
    }



    /** PreciseShardingAlgorithm的重写 */
    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
        String s = buildShardingTable(preciseShardingValue.getLogicTableName(), preciseShardingValue.getValue());
        return s;
    }

    /**
     * 构建分片后的表名
     * @param logicTableName
     * @param date
     * @return
     */
    private String buildShardingTable(String logicTableName, String date) {

        StringBuffer stringBuffer = new StringBuffer(logicTableName).append("_").append(date, 0, 4);
        if (logicTableName.startsWith("month_table") ) {
            // 月分表
           stringBuffer = new StringBuffer(logicTableName).append("_").append(date, 0, 4)
                    .append(date, 5, 7);
        }
        return stringBuffer.toString();
    }

}

4、注意事项

(1)分片主键不能修改。

(2)分表后如果需指定表,入参需使用例如 ${tableSuf}

{}和#{}的区别:{}参数不会携带'',但#{}会携带。

实施sharding-jdbc,一些非常痛的注意点 - 掘金 (juejin.cn)

相关推荐
码语智行5 分钟前
地图上图、空间拓扑查询示例
java·arcgis
苍何8 分钟前
一个令人惊艳的开源项目,Agent Skill 开始自进化了?
后端
程序员黑豆18 分钟前
AI全栈开发 - Java:变量
java·前端·ai编程
我是一颗柠檬19 分钟前
【Java项目技术亮点】分库分表+数据路由策略:单表5000万后的架构升级方案
java·开发语言·分布式·架构
布朗克16827 分钟前
25 IO流高级操作——序列化、NIO与Files工具类
java·数据库·io·nio
小研说技术32 分钟前
Spring AI实现rag流程(简易版)
java·后端
亓才孓37 分钟前
【本地项目引用外部库的类,想修改字段遇到的请缓存的问题】
java·maven
小林敲代码77881 小时前
记录一下IDEA中很多变量变色的方案
java·开发语言·spring boot·idea
Nturmoils1 小时前
自增主键别只会 auto_increment,先把值从哪来讲清楚
数据库·后端
南知意-1 小时前
IDEA 2026.1最新版安装教程
java·ide·intellij-idea·idea安装·idea激活