Springboot3 + shardingsphere-jdbc5.5.2 按年月分表(动态创建表)

1、使用 shardingsphere 动态创建刷新节点

(这个方式 在最新5.3以上的版本已经不支持自定义动态刷新actualDataNodes节点了。

,但是我又不想一次创建所有表(说不定什么时候就会修改表结构)那么该怎么搞呢,我这里提供一个曲线方案。

2、任务创建下一年的表。

原始表用来复制创建

任务类

复制代码
 /**
     * 开启拉取任务(Bean模式)以年为单位创建 每年最后一天创建下一年的表
     */
    @XxlJob("createMessageTableJobHandler")
    public void createMessageTableJobHandler() throws Exception {
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy");
        String s = format.format(date);
        // 创建下一年的表
        Integer data = Integer.parseInt(s) + 1;
        // 一次性创建连续两年的表
        for (MessageCreatTableEnum value : MessageCreatTableEnum.values()) {
            StringBuffer name1 =  new StringBuffer(value.getCode() + StringPool.UNDERSCORE + data)  ;
            StringBuffer name2=  new StringBuffer(value.getCode() + StringPool.UNDERSCORE + (data+1))  ;
            createTable(value, name1.toString(),name2.toString());
        }
        System.out.println(1);
    }

    /**
     * 创建指定年的分片
     * @param value
     * @param table
     * @param tableNext
     */
    private     void createTable(MessageCreatTableEnum value, String table, String tableNext){
        try {
            Connection connection = dataSource.getConnection();
            Statement st = connection.createStatement();
            st.setQueryTimeout(10);
            // 使用st.execute 会卡死 st.executeUpdate  虽然会报错 但是他会执行创建表sql 不影响功能
            st.executeUpdate("CREATE TABLE IF NOT EXISTS `" + table + "` LIKE `" + value.getCode() + "`;" +
                    "CREATE TABLE IF NOT EXISTS `" + tableNext + "` LIKE `" + value.getCode() + "`;");
        } catch (SQLException e) {
            log.error(">>>>>>>>>> 这里本来就会抛异常 但是不影响 创建sql执行:{}", e.getMessage(), e);
        }
        
    }

3、sharding-jdbc-dev.yaml 配置

复制代码
dataSources:
  master:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    jdbcUrl: jdbc:mysql://127.0.0.1:3306/sms?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=false
    username: root
    password: 123456
    connectionTimeout: 30000
    idleTimeout: 600000
    maxLifetime: 1800000
    maximumPoolSize: 10
    minimumIdle: 5
rules:
  ###  数据库读写分离配置
  - !READWRITE_SPLITTING
    dataSourceGroups:
      ### 读写数据库别名
      master_ds:
        writeDataSourceName: master
        readDataSourceNames:
          - master
        transactionalReadQueryStrategy: PRIMARY
        loadBalancerName: random
    #负载均衡算法轮询
    loadBalancers:
      random:
        type: RANDOM
  #单表配置
  - !SINGLE
    tables:
      - master_ds.*
    defaultDataSource: master_ds
复制代码
- !SHARDING
  tables:
    message_data:
      actualDataNodes: master_ds.message_data_$->{2025..2100}
      tableStrategy:
        standard:
          shardingColumn: create_time
          shardingAlgorithmName: message_data_year
  shardingAlgorithms:
    message_data_year:
      type: INTERVAL
      props:
        datetime-pattern: "yyyy-MM-dd HH:mm:ss"
        ## 设置分片开始时间
        datetime-lower: "2025-01-01 00:00:00"
        ## 设置分片结束时间
        datetime-upper: "2100-12-31 23:59:59"
        sharding-suffix-pattern: "yyyy"
        datetime-interval-amount: 1
        datetime-interval-unit: YEARS
复制代码
props:
  sql-show: true

4、如何命中分片测试(关键点)

由于我们超前配置了分片表(到2100年)但是数据库并没有生成这个些表。每次操作如果没有命中分片字段策略,会检索所有表,报异常。

所以在每次保存 查询操作的时候一定要传递(create_time)字段值。

用来命中分片规则,如果不传递会默认查询原始表。

以mybatis为例

保存必须床底分片字段

查询 设置分片范围 比如id查询为例 除了传递id 还要传递时间 用来命中指定分片。

如果懒可以,直接 lt 当前时间(这个会查询比当前时间小的所有表,查询多次库,性能差点)

相关推荐
历程里程碑10 分钟前
普通数组----合并区间
java·数据结构·python·算法·leetcode·职场和发展·tornado
程序员泠零澪回家种桔子29 分钟前
Spring AI框架全方位详解
java·人工智能·后端·spring·ai·架构
CodeCaptain37 分钟前
nacos-2.3.2-OEM与nacos3.1.x的差异分析
java·经验分享·nacos·springcloud
Anastasiozzzz1 小时前
Java Lambda 揭秘:从匿名内部类到底层原理的深度解析
java·开发语言
骇客野人2 小时前
通过脚本推送Docker镜像
java·docker·容器
铁蛋AI编程实战2 小时前
通义千问 3.5 Turbo GGUF 量化版本地部署教程:4G 显存即可运行,数据永不泄露
java·人工智能·python
晚霞的不甘2 小时前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
SunnyDays10112 小时前
使用 Java 冻结 Excel 行和列:完整指南
java·冻结excel行和列
摇滚侠2 小时前
在 SpringBoot 项目中,开发工具使用 IDEA,.idea 目录下的文件需要提交吗
java·spring boot·intellij-idea
云姜.2 小时前
java多态
java·开发语言·c++