springboot,jpa, druid, sharding5.1.2 按日分表配置

springbootApplication要排除druid的datasource,否则会与shardingsphere的配置冲突,加上如下注解:
@SpringBootApplication(exclude = {DruidDataSourceAutoConfigure.class})
@EnableTransactionManagement
@EnableJpaAuditing(auditorAwareRef = "auditorAware")
application-dev.yml配置文件如下:
#配置数据源
spring:
  shardingsphere:
    datasource:
      names: ds
      ds:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/sx_radar?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
        password: root
        username: root
        # 初始连接数
        initial-size: 5
        # 最小连接数
        min-idle: 15
        # 最大连接数
        max-active: 30
        # 超时时间(以秒数为单位)
        remove-abandoned-timeout: 180
        # 获取连接超时时间
        max-wait: 3000
        # 连接有效性检测时间
        time-between-eviction-runs-millis: 60000
        # 连接在池中最小生存的时间
        min-evictable-idle-time-millis: 300000
        # 连接在池中最大生存的时间
        max-evictable-idle-time-millis: 900000
        # 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除
        test-while-idle: true
        # 指明是否在从池中取出连接前进行检验,如果检验失败, 则从池中去除连接并尝试取出另一个
        test-on-borrow: true
        # 是否在归还到池中前进行检验
        test-on-return: false
        # 检测连接是否有效
        validation-query: select 1
        # 配置监控统计
        webStatFilter:
          enabled: true
        stat-view-servlet:
          enabled: true
          url-pattern: /druid/*
          reset-enable: false
        filter:
          stat:
            enabled: true
            # 记录慢SQL
            log-slow-sql: true
            slow-sql-millis: 1000
            merge-sql: true
          wall:
            config:
              multi-statement-allow: true
    rules:
      sharding:
        tables:
          #逻辑表  下面是节点表,分表后还有数据在原来的表,所有查询节点需要加上原来的表
          sx_radar_fog:
            actual-data-nodes: ds.sx_radar_$->{20221001..20301220}_fog
            table-strategy:
              standard:
                sharding-column: data_time
                shardingAlgorithmName: createtime-day
          sx_radar_visibility:
            actual-data-nodes: ds.sx_radar_$->{20221001..20301220}_visibility
            table-strategy:
              standard:
                sharding-column: data_time
                shardingAlgorithmName: createtime-day
        shardingAlgorithms:
          createtime-day:  #分片算法名称
            type: CLASS_BASED  # 分片算法配置:自定义类
            props:
              strategy: standard
              algorithmClassName: com.test.config.CreateTimeDayTableShardingAlgorithm  #自定义分片类
    props:
      sql-show: true

按天分表算法转自sharding-demo-5.1.2: sharding-demo-5.1.2 (gitee.com)

package com.test.config;

import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;

import java.sql.Timestamp;
import java.util.Collection;
import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Range;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;

import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 按天分表实现
 * @author DS
 */
public class CreateTimeDayTableShardingAlgorithm
        implements StandardShardingAlgorithm<Timestamp>, CreateTimeShardingAlgorithm {

    private static final String FORMAT_LINK_DAY = "yyyyMMdd";

    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames,
                                         RangeShardingValue<Timestamp> shardingValue) {
        Range<Timestamp> valueRange;
        valueRange = shardingValue.getValueRange();
        LocalDateTime start = null;
        try {
            start = valueRange.lowerEndpoint().toLocalDateTime();
        }
        catch (Exception e) {
            start = LocalDateTime.now().minusDays(15L);
        }
        LocalDateTime end = null;
        try {
            end = valueRange.upperEndpoint().toLocalDateTime();
        }
        catch (Exception e) {
            end = LocalDateTime.now();
        }
        Set<String> suffixList = new HashSet<>();
        Iterator<String> iterator = availableTargetNames.iterator();
        String tableName = iterator.next();
        String name = tableName.substring(0, tableName.lastIndexOf("_"));
        if (start != null && end != null) {
            String startName = DateUtil.format(start, FORMAT_LINK_DAY);
            String endName = DateUtil.format(end, FORMAT_LINK_DAY);
            while (!startName.equals(endName)) {
                if (availableTargetNames.contains(name + "_" + startName)) {
                    suffixList.add(name + "_" + startName);
                }
                start = start.plusDays(1L);
                startName = DateUtil.format(start, FORMAT_LINK_DAY);

            }
            if (availableTargetNames.contains(name + "_" + endName)) {
                suffixList.add(name + "_" + endName);
            }
        }
        if (CollectionUtils.isNotEmpty(suffixList)) {
            return suffixList;
        }

        return availableTargetNames;
    }

    @Override
    public Properties getProps() {
        return null;
    }

    @Override
    public void init(Properties properties) {
        // 空
    }

    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Timestamp> shardingValue) {
        LocalDateTime time = shardingValue.getValue().toLocalDateTime();
        DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern(FORMAT_LINK_DAY);
        String format = dtf2.format(time);
        for (String str : availableTargetNames) {
            if (str.contains(format)) {
                return str;
            }
        }
        return null;
    }

    @Override
    public String buildNodesSuffix(LocalDate date) {
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(FORMAT_LINK_DAY);
        return date.format(dateFormatter);
    }

    @Override
    public LocalDate buildNodesBeforeDate(LocalDate date) {
        return date.minusDays(1);
    }

    @Override
    public LocalDate buildNodesAfterDate(LocalDate date) {
        return date.plusDays(1);
    }

}
package com.test.config;

import org.apache.commons.lang3.StringUtils;
import org.apache.shardingsphere.driver.jdbc.core.datasource.ShardingSphereDataSource;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

/**
 * @author GDS
 *
 * 跟据创建时间分表的接口
 */

public interface CreateTimeShardingAlgorithm {

    /**
     * 将日期转换为分表的后缀格式
     * @param date
     * @return
     */
    String buildNodesSuffix(LocalDate date);

    /**
     * 分表的阶梯方式,物理表每次递增规则,返回date的后一天或一个月或一年
     * @param date
     * @return
     */
    LocalDate buildNodesAfterDate(LocalDate date);

    /**
     * 分表的阶梯方式,物理表每次递减规则,返回date的前一天或一个月或一年
     * @param date
     * @return
     */
    LocalDate buildNodesBeforeDate(LocalDate date);

    /**
     * 构建可用表的nodes
     * @param tableName 表名
     * @param count 需要表的数量
     * @return 物理表的集合,用,号拼接
     */
    default String buildNodes(String tableName, Integer count) {
        List<String> tableNameList = new ArrayList<>();

        LocalDate today = LocalDate.now();

        for (int i = 0; i < count; i++) {
            tableNameList.add("db0." + tableName + "_${'" + buildNodesSuffix(today) + "'}");
            today = buildNodesBeforeDate(today);
        }
        return StringUtils.join(tableNameList, ",");
    }

    default void createTables(ShardingSphereDataSource dataSource, String tableName, Integer count) {

        try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement()) {

            LocalDate today = LocalDate.now();
            String oldTableName = "";
            String newTableName = "";
            for (int i = 0; i < count; i++) {
                oldTableName = tableName + "_" + buildNodesSuffix(today);
                today = buildNodesAfterDate(today);
                newTableName = tableName + "_" + buildNodesSuffix(today);
                statement.execute("create table IF NOT EXISTS `" + newTableName + "` like  `" + oldTableName + "`");
            }
        }
        catch (SQLException throwables) {
            throw new RuntimeException("建表失败");
        }

    }

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值