快捷搜索:  汽车  科技

mybatis的1.2级缓存:shardingjdbc5.1 mybatis-plus 3.5按年月单库分表

mybatis的1.2级缓存:shardingjdbc5.1 mybatis-plus 3.5按年月单库分表保存策略分表配置

分表最小日期

  • 指定自定义分表策略实现类、分表字段

分表策略实现类主要包含2个操作:

1)保存策略:数据进行保存操作时会根据分表字段的查出对应的真实数据表名称。

2)查询策略:返回时间范围内的所有真实表名,例:dome_202201 dome_202202 dome_202203。注:必须使用between进行查询才会触发分表的查询策略。

mybatis的1.2级缓存:shardingjdbc5.1 mybatis-plus 3.5按年月单库分表(1)

分表配置

mybatis的1.2级缓存:shardingjdbc5.1 mybatis-plus 3.5按年月单库分表(2)

保存策略

mybatis的1.2级缓存:shardingjdbc5.1 mybatis-plus 3.5按年月单库分表(3)

查询策略

完整配置文件

server: port: 8082 spring: profiles: active: dev main: allow-bean-definition-overriding: true application: name: shardingjdbc-dome jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT 8 shardingsphere: enabled: true props: sql-show: true mode: type: Memory schema: name: multit-tenant datasource: # 配置真实数据源 names: ds0 ds1 ds0: # 配置第 1 个数据源 type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:3306/shardingjdbc-dome?useUnicode=true&characterEncoding=UTF-8&useSSL=true&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true username: root password: 123456 ds1: # 配置第 2 个数据源 type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:3306/shardingjdbc-dome?useUnicode=true&characterEncoding=UTF-8&useSSL=true&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true username: root password: 123456 rules: sharding: # 配置 分片算法 sharding-algorithms: my: # 分片类型 type: CLASS_BASED props: strategy: STANDARD algorithmClassName: com.example.dome.common.YearMonthShardingAlgorithm #引用分表类 tables: dome: # 分表,表名 actual-data-nodes: ds.dome_${2022..2099}0${1..9} ds.test_${2022..2099}1${0..2} #数据分表 table-strategy: # 配置分表策略 standard: sharding-column: create_date sharding-algorithm-name: my readwriteSplitting: data-sources: ds: type: Static loadBalancerName: my props: write-data-source-name: ds0 read-data-source-names: ds1 loadBalancers: my: # 负载均衡算法名称 type: ROUND_ROBIN # 负载均衡算法类型 props: default: 0 mybatis-plus: #指定mapper.xml的位置 mapper-locations: classpath*:mapper/**/*.xml configuration: #开启驼峰命名法转换字段支持 用于对象关系绑定 map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启 SQL 解析缓存注解生效 global-config: sql-parser-cache: true swagger: enable: true logging: config: classpath:logback-spring.xml file.path: logs #项目配置 pro: #程序分表指定初始时间 sysDate: '2022-01-01' 分表策略实现类

import cn.hutool.core.collection.ListUtil; import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.example.dome.config.ProConfig; import com.google.common.collect.Range; import lombok.extern.slf4j.Slf4j; 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 org.springframework.stereotype.Component; import java.util.*; import java.util.stream.Collectors; /** * 根据年月分表规则 */ @Component @Slf4j public class YearMonthShardingAlgorithm implements StandardShardingAlgorithm { //获取系统初始时间,确定安时间分表后的最小表名 public Date getSysDate() { ProConfig proConfig = SpringContextUtil.getBean(ProConfig.class); if (StrUtil.isEmpty(proConfig.getSysDate())) { throw new RuntimeException("未设置系统初始时间"); } return DateUtil.parse(proConfig.getSysDate() "yyyy-MM-dd"); } @Override public void init() { } @Override public String getType() { return null; } //插入策略 @Override public String doSharding(Collection collection PreciseShardingValue preciseShardingValue) { //获取字段值 Date time = null; if (preciseShardingValue.getValue() instanceof String) { time = DateUtil.parse(preciseShardingValue.getValue().toString()); } else { time = (Date) preciseShardingValue.getValue(); } String year = DateUtil.date(time).toString("yyyyMM"); String logicTableName = preciseShardingValue.getLogicTableName(); String tableName = logicTableName "_" year; return tableName; } //处理范围查询 @Override public Collection<String> doSharding(Collection collection RangeShardingValue rangeShardingValue) { //返回数据库节点名称list Collection<String> collect = new ArrayList<>(); //获取查询条件中范围值 Range<String> valueRange = rangeShardingValue.getValueRange(); String lowerDate = valueRange.lowerEndpoint(); //系统时间 Date sysStartTime = getSysDate(); DateTime sst = DateUtil.parseDateTime(lowerDate); if (sysStartTime.compareTo(sst) > 0) { lowerDate = DateUtil.format(sysStartTime "yyyy-MM-dd 00:00:00"); } String upperDate = valueRange.upperEndpoint(); //获取时间段内的所有年月,不会超过当前时间 List<String> suffixList = getSuffixListForRangeByMonth(lowerDate upperDate); suffixList.forEach(yyyyMM -> { collect.add(rangeShardingValue.getLogicTableName() "_" yyyyMM); }); if (collect.size() == 0) { throw new RuntimeException("没有对应的数据表"); } return collect; } /** * 两个日期之间所有月份 */ public List<String> getSuffixListForRangeByMonth(String lowerDate String upperDate) { DateTime st = DateUtil.parseDateTime(lowerDate); DateTime et = DateUtil.parseDateTime(upperDate); DateTime ct = DateUtil.parseDateTime(DateUtil.format(new Date() "yyyy-MM-dd 23:59:59")); //判断结束时间不能大于当前时间 if (et.compareTo(ct) > 0) { et = ct; } List<DateTime> dateTimes = DateUtil.rangeToList(st et DateField.DAY_OF_MONTH); List<String> collect = dateTimes.stream().map(x -> x.toString("yyyyMM")).collect(Collectors.toList()); HashSet h = new HashSet(collect); List<String> suffixList = ListUtil.toList(h); return suffixList; } }结语

希望需要的程序员可以直接使用CTRL V、CTRL C就能实现你的需求那是我写这篇文章最大的成就。

为划水助力!

猜您喜欢: