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)

相关推荐
小松学前端几秒前
第六章 7.0 LinkList
java·开发语言·网络
Wx-bishekaifayuan7 分钟前
django电商易购系统-计算机设计毕业源码61059
java·spring boot·spring·spring cloud·django·sqlite·guava
customer0812 分钟前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
全栈开发圈14 分钟前
新书速览|Java网络爬虫精解与实践
java·开发语言·爬虫
WaaTong16 分钟前
《重学Java设计模式》之 单例模式
java·单例模式·设计模式
面试鸭18 分钟前
离谱!买个人信息买到网安公司头上???
java·开发语言·职场和发展
沈询-阿里1 小时前
java-智能识别车牌号_基于spring ai和开源国产大模型_qwen vl
java·开发语言