framework-sharding-sphere
1.介绍
集成sharding-sphere + seata + framework-dynamic-datasource + aviator 的 framework
以framework-dynamic-datasource为基础构建
集成aviator目的是实现sharding-sphere对yml的三元运算符的支持 从而实现分库或者分表算法 yml 三元配置 省去 java类的配置实现
2.项目结构
framework-sharding-sphere
└─src
└─main
├─java
│ └─com
│ └─yan
│ ├─abstractinterface
│ │ ├─config
│ │ └─shardingAlgorithm
│ ├─config
│ │ └─dynamic
│ │ └─Impl
│ └─shardingsphere
│ └─shardingAlgorithm
└─resources
└─META-INF
└─services
3.pom
这里注意我的上一篇博客 关于dynamic-datasource
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yan</groupId>
<artifactId>framework-sharding-sphere</artifactId>
<version>${project-module.version}</version>
<properties>
<java.version>8</java.version>
<project-module.version>0.0.1-SNAPSHOT</project-module.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<!--2.4以下 Hoxton.SR12-2.2.7.RELEASE 2.4以上2021.0.5-2021.0.5.0 -->
<alibaba-druid.version>1.2.22</alibaba-druid.version>
<!--5.2.0该版本和drud存在冲突sql界面无法使用自动配置进入,
com.alibaba.druid.spring.boot.autoconfigure.stat.DruidFilterConfiguration
配置类filter 配置 和5.2.0版本自动配置存在空指针异常会导致服务无法启动
-->
<!--<shardingsphere.version>5.2.0</shardingsphere.version>-->
<!--5.0.0-alpha 稳定版本-->
<shardingsphere.version>5.0.0-alpha</shardingsphere.version>
<dynamic-datasource.version>3.3.2</dynamic-datasource.version>
<pagehelper-spring-boot-starter.version>1.2.13</pagehelper-spring-boot-starter.version>
<mybatis-plus-spring-boot-starter.version>3.4.3</mybatis-plus-spring-boot-starter.version>
<aviator.version>5.2.0</aviator.version>
<commons-beanutils.version>1.9.4</commons-beanutils.version>
</properties>
<dependencies>
<!--aviator-->
<dependency>
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
<version>${aviator.version}</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>${commons-beanutils.version}</version>
</dependency>
<!--分库分表-->
<!-- ShardingSphere -->
<!-- Sharding-JDBC -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>${shardingsphere.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core</artifactId>
<version>${shardingsphere.version}</version>
</dependency>
<!-- ShardingSphere 对 seata 事务 模式 支持-->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-transaction-core</artifactId>
<version>${shardingsphere.version}</version>
</dependency>
<!--多数据源-->
<dependency>
<groupId>com.yan</groupId>
<artifactId>framework-dynamic-datasource</artifactId>
<version>${project-module.version}</version>
<exclusions>
<exclusion>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${dynamic-datasource.version}</version>
</dependency>
<!--说明:1,为shardingsphere使用druid数据源时,不要使用: druid-spring-boot-starter这个包,
因为它在会启动时自动从配置文件生成datasource,
2.使用druid-spring-boot-starter这个包需要排除 com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
这个自动配置类,因为该自动配置类会生成datasource,从而保证druid监控界面可以正常使用
所以在这里使用druid这个包-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${alibaba-druid.version}</version>
<exclusions>
<exclusion>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${alibaba-druid.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.5.0</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>
4.自定义算法使其支持yml的配置实现
com.yan.abstractinterface.shardingAlgorithm
4.1 AbstractIdShardingAlgorithm
package com.yan.abstractinterface.shardingAlgorithm;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.google.common.collect.Range;
import com.googlecode.aviator.AviatorEvaluator;
import lombok.SneakyThrows;
import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.springframework.core.env.Environment;
import java.util.*;
/**
* @Author yan
* @Date 2024/12/6 23:29:43
* @Description
*/
public interface AbstractIdShardingAlgorithm {
interface ConstantShardingAlgorithm {
String SPOT = ".";
String PREFIX = "_";
String SHARDING_ALGORITHMS_PATH = "spring.shardingsphere.rules.sharding.sharding-algorithms";
String COLUMN_KEY = "column";
String TABLE_INLINE_CUSTOM_KEY = "table-inline-custom";
String CUSTOM_ALGORITHM_EXPRESSION_KEY = "custom-algorithm-expression";
String ALGORITHM_EXPRESSION_KEY = "algorithm-expression";
String PROPS_KEY = "props";
String PROPS_PATH = SHARDING_ALGORITHMS_PATH + SPOT + TABLE_INLINE_CUSTOM_KEY + SPOT + PROPS_KEY;
String CUSTOM_ALGORITHM_EXPRESSION_PATH = PROPS_PATH + SPOT + CUSTOM_ALGORITHM_EXPRESSION_KEY;
String ALGORITHM_EXPRESSION_PATH = PROPS_PATH + SPOT + ALGORITHM_EXPRESSION_KEY;
String TYPE = "CUSTOM_COMPLEX";
String COLUMN_ID_VALUE = "id";
static String replaceTableName(String logicTableName, String key) {
if (key.startsWith(logicTableName)) {
int index = key.indexOf(logicTableName);
key = key.substring(index + logicTableName.length());
}
String keyStr = "$";
if (key.contains(keyStr)) {
int index = key.indexOf(keyStr);
key = key.substring(0, index);
}
return key;
}
static String replaceReal(String expression) {
String prefixStr = "{";
String suffixStr = "}";
if (expression.startsWith(prefixStr) && expression.endsWith(suffixStr)) {
// 找到第一个 { 和 } 的位置
int start = expression.indexOf(prefixStr);
int end = expression.lastIndexOf(suffixStr);
expression = expression.substring(start + 1, end);
}
return expression;
}
}
default String shardingSuffix(String logicTableName, Long idValue) {
return shardingSuffix(logicTableName, (Object) idValue);
}
/**
* 精确路由算法
*
* @param availableTargetNames 可用的表列表(配置文件中配置的 actual-data-nodes会被解析成 列表被传递过来)
* @param shardingValue 精确的值
* @return 结果表
*/
default String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
Long idValue = shardingValue.getValue();
// 根据精确值获取路由表
String logicTableName = shardingValue.getLogicTableName();
String actuallyTableName = logicTableName + shardingSuffix(logicTableName, idValue);
if (availableTargetNames.contains(actuallyTableName)) {
return actuallyTableName;
}
return null;
}
/**
* 范围路由算法
*
* @param availableTargetNames 可用的表列表(配置文件中配置的 actual-data-nodes会被解析成 列表被传递过来)
* @param shardingValue 值范围
* @return 路由后的结果表
*/
default Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Long> shardingValue) {
// 获取到范围查找的最小值,如果条件中没有最小值设置为 tableLowerDate
Range<Long> valueRange = shardingValue.getValueRange();
Long rangeLowerValue = valueRange.hasLowerBound() ? valueRange.lowerEndpoint() : 0l;
Long rangeUpperValue = valueRange.hasUpperBound() ? valueRange.upperEndpoint() : Long.MAX_VALUE;
// 根据范围值获取路由表
List<String> tableNames = new ArrayList<>();
// 过滤那些存在的表
String logicTableName = shardingValue.getLogicTableName();
while (rangeLowerValue > rangeUpperValue) {
String actuallyTableName = logicTableName + shardingSuffix(logicTableName, rangeLowerValue);
if (availableTargetNames.contains(actuallyTableName)) {
tableNames.add(actuallyTableName);
}
rangeLowerValue++;
}
return tableNames;
}
/**
* 泛型 ============
*
* @param logicTableName
* @param idValue
* @param <T>
* @return
*/
@SneakyThrows
default <T> String shardingSuffix(String logicTableName, T idValue) {
String expression = StrUtil.EMPTY;
String prefix = ConstantShardingAlgorithm.PREFIX;
Environment env = SpringUtil.getBean(Environment.class);
String spot = ConstantShardingAlgorithm.SPOT;
String column = env.getProperty(ConstantShardingAlgorithm.PROPS_PATH + spot + ConstantShardingAlgorithm.COLUMN_KEY);
column = StrUtil.isBlank(column) ? ConstantShardingAlgorithm.COLUMN_ID_VALUE : column;
expression = env.getProperty(ConstantShardingAlgorithm.PROPS_PATH + spot + ConstantShardingAlgorithm.CUSTOM_ALGORITHM_EXPRESSION_KEY);
if (StrUtil.isBlank(expression)) {
String algorithmExpression = env.getProperty(ConstantShardingAlgorithm.PROPS_PATH + spot + ConstantShardingAlgorithm.ALGORITHM_EXPRESSION_KEY);
if (StrUtil.isBlank(algorithmExpression)) {
throw new Exception(ConstantShardingAlgorithm.ALGORITHM_EXPRESSION_KEY + " is not null");
}
String[] split = algorithmExpression.split("->");
String prefixTable = split[0];
prefix = ConstantShardingAlgorithm.replaceTableName(logicTableName, prefixTable);
expression = ConstantShardingAlgorithm.replaceReal(split[split.length - 1]);
}
if (StrUtil.isBlank(expression)) {
throw new Exception("expression is null");
}
expression = ConstantShardingAlgorithm.replaceTableName(logicTableName, expression);
expression = ConstantShardingAlgorithm.replaceReal(expression);
Map<String, Object> map = new LinkedHashMap<>();
map.put(column, idValue);
String execute = "";
try {
Object executeReturn = AviatorEvaluator.execute(expression, map);
execute = prefix + executeReturn;
} catch (Exception e) {
throw new Exception("分片算法执行失败");
}
return execute;
}
/**
* 精确路由算法
*
* @param availableTargetNames 可用的表列表(配置文件中配置的 actual-data-nodes会被解析成 列表被传递过来)
* @param shardingValue 精确的值
* @return 结果表
*/
default <T extends Comparable<?>> String doShardingOne(Collection<String> availableTargetNames, PreciseShardingValue<T> shardingValue) {
T idValue = shardingValue.getValue();
// 根据精确值获取路由表
String logicTableName = shardingValue.getLogicTableName();
String actuallyTableName = logicTableName + shardingSuffix(logicTableName, idValue);
if (availableTargetNames.contains(actuallyTableName)) {
return actuallyTableName;
}
return null;
}
/**
* 范围路由算法
*
* @param availableTargetNames 可用的表列表(配置文件中配置的 actual-data-nodes会被解析成 列表被传递过来)
* @param shardingValue 值范围
* @return 路由后的结果表
*/
default <T extends Comparable<?>> Collection<String> doShardingList(Collection<String> availableTargetNames, RangeShardingValue<T> shardingValue) {
// 获取到范围查找的最小值,如果条件中没有最小值设置为 tableLowerDate
Range<T> valueRange = shardingValue.getValueRange();
Long rangeLowerValue = Long.parseLong(String.valueOf(valueRange.hasLowerBound() ? valueRange.lowerEndpoint() : 0l));
Long rangeUpperValue = Long.parseLong(String.valueOf(valueRange.hasUpperBound() ? valueRange.upperEndpoint() : Long.MAX_VALUE));
// 根据范围值获取路由表
List<String> tableNames = new ArrayList<>();
// 过滤那些存在的表
String logicTableName = shardingValue.getLogicTableName();
while (rangeLowerValue > rangeUpperValue) {
String actuallyTableName = logicTableName + shardingSuffix(logicTableName, (T) rangeLowerValue);
if (availableTargetNames.contains(actuallyTableName)) {
tableNames.add(actuallyTableName);
}
rangeLowerValue++;
}
return tableNames;
}
}
4.2 实现AbstractIdShardingAlgorithm==> IdCustomShardingAlgorithm
com.yan.shardingsphere.shardingAlgorithm
IdCustomShardingAlgorithm
package com.yan.shardingsphere.shardingAlgorithm;
import cn.hutool.core.util.StrUtil;
import com.googlecode.aviator.AviatorEvaluator;
import com.yan.abstractinterface.shardingAlgorithm.AbstractIdShardingAlgorithm;
import groovy.util.logging.Slf4j;
import lombok.SneakyThrows;
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.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
/**
* @Author yan
* @Date 2024/12/5 20:54:54
* @Description //自定义分片策略
*/
@Slf4j
public class IdCustomShardingAlgorithm implements AbstractIdShardingAlgorithm, StandardShardingAlgorithm<Long> {
private Properties props = new Properties();
/**
* 返回算法类型,用于标识分片算法。
*
* @return 算法类型字符串
*/
@Override
public String getType() {
return ConstantShardingAlgorithm.TYPE; // 自定义算法类型
}
/**
* 初始化方法,可用于加载配置(如果需要)。
*/
@Override
public void init() {
}
@Override
public Properties getProps() {
return props;
}
@Override
public void setProps(Properties properties) {
this.props = properties;
}
@SneakyThrows
@Override
public String shardingSuffix(String logicTableName, Long idValue) {
String expression = StrUtil.EMPTY;
String prefix = ConstantShardingAlgorithm.PREFIX;
String column = props.getProperty(ConstantShardingAlgorithm.COLUMN_KEY);
column = StrUtil.isBlank(column) ? ConstantShardingAlgorithm.COLUMN_ID_VALUE : column;
expression = props.getProperty(ConstantShardingAlgorithm.CUSTOM_ALGORITHM_EXPRESSION_KEY);
if (StrUtil.isBlank(expression)) {
String algorithmExpression = props.getProperty(ConstantShardingAlgorithm.ALGORITHM_EXPRESSION_KEY);
if (StrUtil.isBlank(algorithmExpression)) {
throw new Exception(ConstantShardingAlgorithm.ALGORITHM_EXPRESSION_KEY + " is not null");
}
String[] split = algorithmExpression.split("->");
String prefixTable = split[0];
prefix = ConstantShardingAlgorithm.replaceTableName(logicTableName, prefixTable);
expression = ConstantShardingAlgorithm.replaceReal(split[split.length - 1]);
}
if (StrUtil.isBlank(expression)) {
throw new Exception("expression is null");
}
expression = ConstantShardingAlgorithm.replaceTableName(logicTableName, expression);
expression = ConstantShardingAlgorithm.replaceReal(expression);
Map<String, Object> map = new LinkedHashMap<>();
map.put(column, idValue);
String execute = "";
try {
Object executeReturn = AviatorEvaluator.execute(expression, map);
execute = prefix + executeReturn;
} catch (Exception e) {
throw new Exception("分片算法执行失败");
}
return execute;
}
/**
* 精确路由算法
*
* @param availableTargetNames 可用的表列表(配置文件中配置的 actual-data-nodes会被解析成 列表被传递过来)
* @param shardingValue 精确的值
* @return 结果表
*/
@Override
public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
return AbstractIdShardingAlgorithm.super.doSharding(availableTargetNames, shardingValue);
}
/**
* 范围路由算法
*
* @param availableTargetNames 可用的表列表(配置文件中配置的 actual-data-nodes会被解析成 列表被传递过来)
* @param shardingValue 值范围
* @return 路由后的结果表
*/
@Override
public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Long> shardingValue) {
return AbstractIdShardingAlgorithm.super.doSharding(availableTargetNames, shardingValue);
}
}
5. AbstractDynamicDataSource 实现(可选)
当然也可以不实现,直接使用DefaultDynamicDataSourceImpl 就行
package com.yan.config.dynamic.Impl;
import com.yan.abstractinterface.config.dynamic.AbstractDynamicDataSource;
import org.springframework.stereotype.Service;
/**
* @Author yan
* @Date 2024/10/25 上午9:21:31
* @Description
*/
@Service
public class ShardingSphereDynamicDataSourceImpl implements AbstractDynamicDataSource {
}
6.resources配置
在resources.META-INF.services下
新建文件org.apache.shardingsphere.sharding.spi.ShardingAlgorithm
文件内容:
com.yan.shardingsphere.shardingAlgorithm.IdCustomShardingAlgorithm
6.1基础yml配置
application.yml
spring:
main:
allow-circular-references: true
allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册
####################################################################################################################################################################
autoconfigure:
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure #去除druid配置
datasource:
####################################################################################################################################################################
type: com.alibaba.druid.pool.DruidDataSource
druid:
filter:
stat:
enabled: true
stat-view-servlet:
enabled: true
loginUsername: admin
loginPassword: 123456
web-stat-filter:
enabled: true
dynamic:
druid:
# 初始化连接数
initialSize: 10
# 最小连接池数量
minIdle: 20
# 最大连接池数量
maxActive: 100
# 配置连接等待超时的时间,单位为毫秒
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictionIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictionIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
# testOnBorrow 能够确保我们每次都能获取到可用的连接,但是如果设置为 true,则每次获取连接时候都要到数据库验证连接有效性,这在高并发的时候会造成性能下降,
# 可以将 testOnBorrow 设置成 false,testWhileIdle 设置成 true 这样能获得比较好的性能
testWhileIdle: true
testOnBorrow: false
# testOnBorrow 和 testOnReturn 在生产环境一般是不开启的,主要是性能考虑。
testOnRetrun: false
####################################################################################################################################################################
# sharding-sphere 数据源 公共配置
shardingsphere:
datasource:
common:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
initial-size: ${spring.datasource.dynamic.druid.initialSize}
min-idle: ${spring.datasource.dynamic.druid.minIdle}
maxActive: ${spring.datasource.dynamic.druid.maxActive}
# 配置获取连接等待超时的时间
maxWait: ${spring.datasource.dynamic.druid.maxWait}
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: ${spring.datasource.dynamic.druid.timeBetweenEvictionRunsMillis}
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: ${spring.datasource.dynamic.druid.minEvictionIdleTimeMillis}
#Oracle需要打开注释
#validationQuery: ${spring.datasource.dynamic.druid.validationQuery}
testWhileIdle: ${spring.datasource.dynamic.druid.testWhileIdle}
testOnBorrow: ${spring.datasource.dynamic.druid.testOnBorrow}
testOnReturn: ${spring.datasource.dynamic.druid.testOnReturn}
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,slf4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
wall:
multi-statement-allow: true
#================================================================================================================================================================================
# mybatis plus 配置
#================================================================================================================================================================================
mybatis-plus:
# 设置Mapper文件位置
mapper-locations: classpath:mapper/*.xml, classpath:mapper/**/*.xml
#配置
configuration:
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
# 使用JDBC的getGeneratedKeys,获取数据库自增主键值
use-generated-keys: true
# 使用列别名
use-column-label: true
# 驼峰下划线转换
map-underscore-to-camel-case: true
logging:
level:
com.yan.dao: debug
#================================================================================================================================================================================
sharding:
transaction:
seata:
at:
enable: true
client:
application:
id: archetype
transaction:
service:
group: default_tx_group
6.2 demo.yml:
#使用 该配置如报错请注释DynamicDataSourceConfig,AbstractDynamicDataSource 配置类 和依赖 dynamic-datasource 和@DS 注解 多数据源配置
spring:
shardingsphere:
props:
sql-show: true
datasource:
names: sharding
sharding:
type: ${spring.shardingsphere.datasource.common.type}
driver-class-name: ${spring.shardingsphere.datasource.common.driver-class-name}
#使用 druid jdbc-url替换url
# type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://127.0.0.1:3306/sharding?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&allowMultiQueries=true
# type: com.zaxxer.hikari.HikariDataSource
# jdbc-url: jdbc:mysql://127.0.0.1:3306/dev?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&allowMultiQueries=true
# driver-class-name: com.mysql.cj.jdbc.Driver
username: username
password: password
rules:
sharding:
sharding-algorithms:
# 分表算法
table-inline:
type: INLINE
props:
algorithm-expression: sys_user_$->{id % 2}
table-inline-02:
type: INLINE
props:
#有效 这种三元写法 原生是不支持的 IdCustomShardingAlgorithm 已经支持完善
algorithm-expression: sys_user_$->{(id<10?0:(id>20?0:1))}
table-inline-custom:
type: CUSTOM_COMPLEX
props:
#有效
column: id
algorithm-expression: sys_user_$->{(id % 2)}
# custom-algorithm-expression: (id<10?0:(id>20?0:1))
# 分库算法 只分表不使用
# database-inline:
# type: INLINE
# props:
# algorithm-expression: ds$->{sharding_key % 2}
tables:
sys_user2_s:
actual-data-nodes: sharding.sys_user_$->{0..1}
key-generate-strategy:
column: id
key-generator-name: snowflake
# 分库策略 只分表不使用
# database-strategy:
# standard:
# sharding-column: sharding_key
# sharding-algorithm-name: database-inline
# 分表策略
table-strategy:
standard:
sharding-column: id
sharding-algorithm-name: table-inline
sys_user:
# 实际数据节点
actual-data-nodes: sharding.sys_user_$->{0..1}
key-generate-strategy:
column: id
key-generator-name: snowflake
# 表分片策略,指定分片列和自定义算法类
table-strategy:
standard:
sharding-column: id
# algorithm-class-name:
sharding-algorithm-name: table-inline-custom
# complex:
# sharding-columns: id
# algorithm-class-name: com.yan.shardingsphere.shardingAlgorithm.IdBasedShardingAlgorithm
key-generators:
snowflake:
type: SNOWFLAKE
props:
worker-id: 1
# mode:
# type: Standalone
# repository:
# type: File
# overwrite: true