首先,准备一个分片的表
CREATE TABLE `t_log` (
`id` bigint NOT NULL AUTO_INCREMENT,
`log` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`time` varchar(12) DEFAULT NULL,
`created_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
接着,创建一个新的项目,引入相关依赖,这用的是sharding-jdbc 4.0.0-RC1版本
org.springframework.boot
spring-boot-starter-parent
1.5.3.RELEASE
1.8
UTF-8
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-web
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.0
mysql
mysql-connector-java
8.0.22
runtime
org.apache.shardingsphere
sharding-jdbc-spring-boot-starter
4.0.0-RC1
com.alibaba
druid-spring-boot-starter
1.1.21
org.springframework.boot
spring-boot-maven-plugin
org.mybatis.generator
mybatis-generator-maven-plugin
1.3.2
true
false
mysql
mysql-connector-java
8.0.22
添加配置:
# 配置存放到内存中
spring.shardingsphere.mode.type=Memory
# 打印sql日志
spring.shardingsphere.props.sql.show=true
# 配置数据源
spring.shardingsphere.datasource.names=ds
spring.shardingsphere.datasource.ds.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds.url=jdbc:mysql://192.168.3.4:3306/sharding?autoReconnect=true&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false
spring.shardingsphere.datasource.ds.username=root
spring.shardingsphere.datasource.ds.password=root
# 配置数据节点,这里是按月分表,时间范围设置在202201 ~ 210012
spring.shardingsphere.sharding.tables.t_log.actual-data-nodes=ds.t_log_$->{2022..2100}0$->{1..9},ds.t_log_$->{2022..2100}1$->{0..2}
# 使用标准分片策略,配置分片字段
spring.shardingsphere.sharding.tables.t_log.table-strategy.standard.sharding-column=time
# 配置精确、范围查询分片算法
spring.shardingsphere.sharding.tables.t_log.table-strategy.standard.precise-algorithm-class-name=com.example.springboot.algorithm.TimeShardingAlgorithm
spring.shardingsphere.sharding.tables.t_log.table-strategy.standard.range-algorithm-class-name=com.example.springboot.algorithm.TimeShardingAlgorithm
# 配置主键以及生成算法
spring.shardingsphere.sharding.tables.t_log.key-generator.column=id
spring.shardingsphere.sharding.tables.t_log.key-generator.type=SNOWFLAKE
这里要注意下precise-algorithm是配置精确分片算法实现类(如=、in),range-algorithm是配置范围分片算法实现类(如between and),实现如下:
package com.example.springboot.algorithm;
import com.google.common.collect.Range;
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.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collection;
/**
* 分片算法,按月分片
*/
public class TimeShardingAlgorithm implements PreciseShardingAlgorithm, RangeShardingAlgorithm {
/**
* 需要空构造方法
*/
public TimeShardingAlgorithm() {}
/**
* 时间格式
*/
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
/**
* 精确分片
* @param collection
* @param preciseShardingValue
* @return
*/
@Override
public String doSharding(Collection collection, PreciseShardingValue preciseShardingValue) {
return buildShardingTable(preciseShardingValue.getLogicTableName(), preciseShardingValue.getValue());
}
/**
* 构建分片后的表名
* @param logicTableName
* @param date
* @return
*/
private String buildShardingTable(String logicTableName, String date) {
StringBuffer stringBuffer = new StringBuffer(logicTableName).append("_").append(date, 0, 6);
return stringBuffer.toString();
}
/**
* 范围分片
* @param collection
* @param rangeShardingValue
* @return
*/
@Override
public Collection doSharding(Collection collection, RangeShardingValue rangeShardingValue) {
Range valueRange = rangeShardingValue.getValueRange();
String lower = valueRange.lowerEndpoint();
String upper = valueRange.upperEndpoint();
LocalDate start = LocalDate.parse(lower, DATE_TIME_FORMATTER);
LocalDate end = LocalDate.parse(upper, DATE_TIME_FORMATTER);
Collection tables = new ArrayList<>();
while (start.compareTo(end) <= 0) {
tables.add(buildShardingTable(rangeShardingValue.getLogicTableName(), start.format(DATE_TIME_FORMATTER)));
start = start.plusMonths(1L);
}
// collection配置的数据节点表,这里是排除不存在配置中的表
collection.retainAll(tables);
return collection;
}
}