太仓市住房和城乡建设局官方网站,wordpress 添加微博,关键词优化下拉管家,wordpress企业主题模板下载文章目录 ShardingJDBC快速入门修改雪花算法和分表策略核心概念分片算法简单INLINE分片算法STANDARD标准分片算法COMPLEX_INLINE复杂分片算法CLASS_BASED自定义分片算法HINT_INLINE强制分片算法 注意事项 ShardingJDBC
Git地址
快速入门
现在我存在两个数据库#xff0c;并… 文章目录 ShardingJDBC快速入门修改雪花算法和分表策略核心概念分片算法简单INLINE分片算法STANDARD标准分片算法COMPLEX_INLINE复杂分片算法CLASS_BASED自定义分片算法HINT_INLINE强制分片算法 注意事项 ShardingJDBC
Git地址
快速入门
现在我存在两个数据库并且各自都有两个数据表。我现在先新增一批用户分别插入两个数据库的多张数据表中 基本环境搭建
实体类
Data
EqualsAndHashCode(callSuper false)
Accessors(chain true)
// 注意我这里给的表名是sys_user 这是一个逻辑表名 而上图中是不存在这个数据表的
TableName(sys_user)
ApiModel(valueUser对象, description用户表)
public class User implements Serializable {private static final long serialVersionUID 1L;/*** 实体类中的属性最好不用使用id因为mybatisplus会自动识别id属性并在新增时使用雪花算法为id属性赋值。* 而不会使用ShardingSphere的雪花算法生成如果一定要使用id属性名那么就要加上TableId(value uid, type IdType.AUTO)** 也不要在分片键上使用 TableId(value uid, type IdType.ASSIGN_ID) 这样是使用的mybatisplus的雪花算法生成的key* 也不会使用ShardingSphere的雪花算法生成*/ApiModelProperty(value uid)
// TableId(value uid, type IdType.ASSIGN_ID)private Long uid;ApiModelProperty(value 用户名)private String username;ApiModelProperty(value 密码)private String password;ApiModelProperty(value 姓名)private String name;ApiModelProperty(value 描述)private String description;ApiModelProperty(value 状态1正常 0停用)private Integer status;ApiModelProperty(value 创建时间)JsonFormat(patternyyyy-MM-dd HH:mm:ss,timezone GMT8)TableField(fill FieldFill.INSERT)private Date createTime;ApiModelProperty(value 最后修改时间)JsonFormat(patternyyyy-MM-dd HH:mm:ss,timezone GMT8)TableField(fill FieldFill.INSERT_UPDATE)private Date updateTime;
}Mapper接口
Mapper
public interface UserMapper extends BaseMapperUser {
}maven依赖
!-- shardingJDBC核心依赖 --
dependencygroupIdorg.apache.shardingsphere/groupIdartifactIdshardingsphere-jdbc-core-spring-boot-starter/artifactIdversion5.2.1/versionexclusionsexclusionartifactIdsnakeyaml/artifactIdgroupIdorg.yaml/groupId/exclusion/exclusions
/dependency!-- 坑爹的版本冲突 --
dependencygroupIdorg.yaml/groupIdartifactIdsnakeyaml/artifactIdversion1.33/version
/dependency!-- SpringBoot依赖 --
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter/artifactIdexclusionsexclusionartifactIdsnakeyaml/artifactIdgroupIdorg.yaml/groupId/exclusion/exclusions
/dependency!-- 数据源连接池 --
!--注意不要用这个依赖他会创建数据源跟上面ShardingJDBC的SpringBoot集成依赖有冲突 --
!-- dependency--
!-- groupIdcom.alibaba/groupId--
!-- artifactIddruid-spring-boot-starter/artifactId--
!-- version1.1.20/version--
!-- /dependency--
dependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.1.20/version
/dependency上方 snakeyaml 依赖冲突会报下面的错误
Description:An attempt was made to call a method that does not exist. The attempt was made from the following location:org.apache.shardingsphere.infra.util.yaml.constructor.ShardingSphereYamlConstructor$1.init(ShardingSphereYamlConstructor.java:44)The following method did not exist:org.apache.shardingsphere.infra.util.yaml.constructor.ShardingSphereYamlConstructor$1.setCodePointLimit(I)VThe methods class, org.apache.shardingsphere.infra.util.yaml.constructor.ShardingSphereYamlConstructor$1, is available from the following locations:jar:file:/D:/softwareDev/maven/myMaven/repository/org/apache/shardingsphere/shardingsphere-infra-util/5.2.1/shardingsphere-infra-util-5.2.1.jar!/org/apache/shardingsphere/infra/util/yaml/constructor/ShardingSphereYamlConstructor$1.classThe class hierarchy was loaded from the following locations:null: file:/D:/softwareDev/maven/myMaven/repository/org/apache/shardingsphere/shardingsphere-infra-util/5.2.1/shardingsphere-infra-util-5.2.1.jarorg.yaml.snakeyaml.LoaderOptions: file:/D:/softwareDev/maven/myMaven/repository/org/yaml/snakeyaml/1.26/snakeyaml-1.26.jarAction:Correct the classpath of your application so that it contains a single, compatible version of org.apache.shardingsphere.infra.util.yaml.constructor.ShardingSphereYamlConstructor$1yml配置文件的内容
server:port: 8084spring:shardingsphere:props:# 打印shardingjdbc的日志 shardingsphere5之前的版本配置项是 spring.shardingsphere.props.sql.show而这里是sql-showsql-show: true# 数据源配置datasource:# 虚拟库的名字并指定对应的真实库names: hsdb0,hsdb1hsdb0:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/sharding_sphere1?serverTimezoneUTCuseSSLfalseuseUnicodetruecharacterEncodingUTF-8username: rootpassword: 1234hsdb1:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/sharding_sphere2?serverTimezoneUTCuseSSLfalseuseUnicodetruecharacterEncodingUTF-8username: rootpassword: 1234# 分布式序列算法配置rules:sharding:key-generators:# 雪花算法生成Long类型主键。# alg_snowflake为我们程序员自定义的字符串名字可以更改alg_snowflake:type: SNOWFLAKE # 建议使用COSID_SNOWFLAKE雪花算法避免数据分布不均匀props:worker:id: 1sharding-algorithms:# 指定分库策略 按2取模方式 sys_user_db_alg是我们程序员自定义的字符串名字可以更改sys_user_db_alg:type: MODprops:sharding-count: 2# 指定分表策略 INLINE按单一分片键分表sys_user_tbl_alg:type: INLINEprops:# 通过uid对2取模 1 最终就会是使用sys_user1 sys_user2两张数据表algorithm-expression: sys_user$-{uid%21}# 指定分布式主键生成策略tables:# sys_user为虚拟表名可以更改但需要和实体类中的表名对应上sys_user:# 指定虚拟表的分片键以及分片键的生成策略key-generate-strategy:# 指定分片建为 uid 这个是和数据表中的字段对应的column: uid# 指定分片键字段的生成策略 alg_snowflake 也就是我们上面自定义的雪花算法key-generator-name: alg_snowflake# 配置实际分片节点 $-{1..2}表达式的功能就是[1,2] hsdb0.sys_user1 hsdb0.sys_user2 hsdb1.sys_user1 hsdb1.sys_user2actual-data-nodes: hsdb$-{0..1}.sys_user$-{1..2}# 配置分库策略按uid字段取模database-strategy:standard:sharding-column: uidsharding-algorithm-name: sys_user_db_alg# 指定分表策略 standard-按单一分片键进行精确或范围分片table-strategy:standard:sharding-column: uidsharding-algorithm-name: sys_user_tbl_alg测试类进行新增10条记录
SpringBootTest
RunWith(SpringRunner.class)
public class TestShardingJDBC {Autowiredprivate UserMapper userMapper;Testpublic void testAdd(){for (int i 0; i 10; i) {User user new User();user.setUsername(husahng i);user.setPassword(123456);userMapper.insert(user);}}
}日志信息 插入结果我们能发现目前新增的数据被分到了两张数据表中数据的分布并不平衡。这是因为我们在yml配置文件中指定的分库策略和分表策略导致的
我们的分库策略是根据uid%2 最终决定使用哪一个数据库分表策略是uid%21 。
所以就导致了如果uid为偶数就会存放在hsdb0.sys_user1数据表如果uid是奇数就会存放在hsdb1.sys_user2数据表 修改雪花算法和分表策略
我们接下来就修改一下分表策略
而将sys_user_tbl_alg的计算表达式从sys_user$-{uid%21}改成 sys_user$-{((uid1)%4).intdiv(2)1} 后理论上如果uid是连续递增的就可以将数据均匀分到四个表里。但是snowflake雪花算法生成的ID并不是连续的所以有时候还是无法分到四个表。
如下图所示已经修改了分表策略但还是只分到hsdb0.sys_user1数据表和hsdb1.sys_user2数据表 20240803120302397.pngpos_idimg-SabPy9cD-1722676476932) 所以我们还需要修改一下雪花算法不使用snowflake雪花算法。关于这一块后续文档会详细介绍这里就简单使用mybatisplus的主键通过雪花算法生成
TableId(value uid, type IdType.ASSIGN_ID)
private Long uid;或者是使用COSID_SNOWFLAKE雪花算法 此时数据就平衡的插入到多张数据表中了 核心概念 虚拟库 ShardingSphere的核心就是提供一个具备分库分表功能的虚拟库他是一个ShardingSphereDatasource实例。应用程序只需要像操作单数据源一样访问这个ShardingSphereDatasource即可。 上方案例中hsdb1 hsdb2就是虚拟库 真实库 实际保存数据的数据库。真实库被包含在ShardingSphereDataSource实例中由ShardingSphere来决定未来使用哪一个真实库 上方案例中sharding_sphere1和sharding_sphere2就是真实库 逻辑表 应用程序直接操作的逻辑表。 上方案例中sys_user就是逻辑表 真实表 真实保存数据的表。逻辑表和真实表的表名不需要一致但需要有一致的表结构。应用程序可以维护一个真实表与逻辑表的对应关系。 上方案例中sys_ser1 sys_user2就是真实表 分布式主键生成算法 给逻辑表生成唯一的主键。 由于逻辑表的数据是分布在多个真实表当中的所以单表的索引就无法保证逻辑表的ID唯一性。ShardingSphere集成了几种常见的基于单机生成的分布式主键生成器。比如SNOWFLAKECOSID_SNOWFLAKE雪花算法可以生成单调递增的long类型的数字主键还有UUIDNANOID可以生成字符串类型的主键。当然ShardingSphere也支持应用自行扩展主键生成算法。比如基于RedisZookeeper等第三方服务自行生成主键。 分片策略 表示逻辑表要如何分配到真实库和真实表当中分为分库策略和分表策略两个部分。 分片策略由分片键和分片算法组成。分片键是进行数据水平拆分的关键字段。如果没有分片键ShardingSphere将只能进行全路由SQL执行的性能会非常差。分片算法则表示根据分片键如何寻找对应的真实库和真实表。 分片算法
简单INLINE分片算法
可以对分片键使用 或者是 in 进行精确查找。uid通过下面的分片表达式计算出要查询的真实库和真实表。
如果in操作涉及到了多个分片 并且 涉及到了多个数据表也会进行多分片多数据表的查询
默认情况下不能使用范围查询
我们现在yml的配置的分表策略是
spring:shardingsphere:rules:sharding:sharding-algorithms:sys_user_tbl_alg:# 分片策略是 INLINEtype: INLINEprops:# 通过(uid1) %4 /2 1algorithm-expression: sys_user$-{((uid1)%4).intdiv(2)1}// 使用 对分片进行精确查询
Test
public void testInline(){QueryWrapperUser queryWrapper new QueryWrapper();queryWrapper.eq(uid, 1819587788580864004L);User user userMapper.selectOne(queryWrapper);System.out.println(user);
}日志信息仅仅查询到一个库的一个表进行查询
Logic SQL: SELECT uid,username,password,name,description,status,create_time,update_time FROM sys_user WHERE (uid ?)Actual SQL: hsdb0 ::: SELECT uid,username,password,name,description,status,create_time,update_time FROM sys_user1
WHERE (uid ?) ::: [1819587788580864004]// in操作 涉及到的都在是一个分片库中
Test
public void testInline(){QueryWrapperUser queryWrapper new QueryWrapper();queryWrapper.in(uid, 1819587788580864004L,1819587788513755138L);ListUser users userMapper.selectList(queryWrapper);System.out.println(users);
}日志信息会查询hsdb0分片库中的sys_user1 和 sys_user2 数据表并通过union关键字进行组合查询
Logic SQL: SELECT uid,username,password,name,description,status,create_time,update_time FROM sys_user WHERE (uid IN (?,?))Actual SQL: hsdb0 ::: SELECT uid,username,password,name,description,status,create_time,update_time FROM sys_user1
WHERE (uid IN (?,?))
UNION
ALL SELECT uid,username,password,name,description,status,create_time,update_time FROM sys_user2
WHERE (uid IN (?,?)) ::: [1819587788580864004, 1819587788513755138, 1819587788580864004, 1819587788513755138]// in操作 涉及到两个分片中的sys_user1数据表
Test
public void testInline(){QueryWrapperUser queryWrapper new QueryWrapper();queryWrapper.in(uid, 1819587788580864004L,1819587788580864003L);ListUser users userMapper.selectList(queryWrapper);System.out.println(users);
}此时我更改一个查询的uid让它涉及到两个分片中的sys_user1数据表此时从打印的日志就可以发现这里只查询了两个分片的sys_user1数据表
Logic SQL: SELECT uid,username,password,name,description,status,create_time,update_time FROM sys_user WHERE (uid IN (?,?))Actual SQL: hsdb0 ::: SELECT uid,username,password,name,description,status,create_time,update_time FROM sys_user1 WHERE (uid IN (?,?)) ::: [1819587788580864004, 1819587788580864003]
Actual SQL: hsdb1 ::: SELECT uid,username,password,name,description,status,create_time,update_time FROM sys_user1 WHERE (uid IN (?,?)) ::: [1819587788580864004, 1819587788580864003]// in操作 涉及到两个分片中的两张数据表主要就是sys_user$-{((uid1)%4).intdiv(2)1}这个分片表达式不能很好的进行区分了
Test
public void testInline(){QueryWrapperUser queryWrapper new QueryWrapper();queryWrapper.in(uid, 1819587788580864004L,1819587784852127745L);ListUser users userMapper.selectList(queryWrapper);System.out.println(users);
}此时我更改一个查询的uid让它设计到两个分片的两个数据表此时从打印的日志就可以发现这里进行了两个分片与两个数据表的查询
Logic SQL: SELECT uid,username,password,name,description,status,create_time,update_time FROM sys_user WHERE (uid IN (?,?))ctual SQL: hsdb0 ::: SELECT uid,username,password,name,description,status,create_time,update_time FROM sys_user1
WHERE (uid IN (?,?)) UNION ALL SELECT uid,username,password,name,description,status,create_time,update_time FROM sys_user2
WHERE (uid IN (?,?)) ::: [1819587788580864004, 1819587784852127745, 1819587788580864004, 1819587784852127745]Actual SQL: hsdb1 ::: SELECT uid,username,password,name,description,status,create_time,update_time FROM sys_user1 WHERE (uid IN (?,?)) UNION ALL SELECT uid,username,password,name,description,status,create_time,update_time FROM sys_user2 WHERE (uid IN (?,?)) ::: [1819587788580864004, 1819587784852127745, 1819587788580864004, 1819587784852127745]STANDARD标准分片算法
使用简单INLINE分片算法它默认情况下不支持范围查询。
我们可以通过添加下面这个参数让它支持范围查询只不过此时的查询是通过全分片路由查询
# 允许在inline策略中使用范围查询。 sys_user_tbl_alg 是自定义名称
spring.shardingsphere.rules.sharding.sharding-algorithms.sys_user_tbl_alg.props.allow-range-query-with-inline-shardingtrueTest
public void testInline(){QueryWrapperUser queryWrapper new QueryWrapper();queryWrapper.between(uid, 1819587788513755138L, 1819587788580864004L);ListUser users userMapper.selectList(queryWrapper);System.out.println(users);
}报错信息 # 添加下面的配置 允许在inline策略中使用范围查询。 sys_user_tbl_alg 是自定义名称
spring.shardingsphere.rules.sharding.sharding-algorithms.sys_user_tbl_alg.props.allow-range-query-with-inline-shardingtrue此时的查询就会通过全分片路由查询 在Class_based自定义分片算法中如果使用标准分片算法则实现下面的接口StandardShardingAlgorithm
public interface StandardShardingAlgorithmT extends Comparable? extends ShardingAlgorithm {String doSharding(CollectionString var1, PreciseShardingValueT var2);// 如果是范围查询那么我们就可以通过使用RangeShardingValue 对象来进行自定义范围查询的分片算法CollectionString doSharding(CollectionString var1, RangeShardingValueT var2);
}COMPLEX_INLINE复杂分片算法
complex_inline复杂分片策略它支持多个分片键。
建议所有的分片键是同一个类型 修改yml配置
# 分表策略-COMPLEX按多个分片键组合分表 sys_user_tbl_alg 为我们自定义字符串 可以修改
spring.shardingsphere.rules.sharding.sharding-algorithms.sys_user_tbl_alg.typeCOMPLEX_INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.sys_user_tbl_alg.props.algorithm-expressionsys_user$-{(uidstatus1)%21}#给sys_user表指定分表策略 sys_user是虚拟表名 按uid, status多个分片键进行组合分片 sys_user_tbl_alg要和上面的对应上
spring.shardingsphere.rules.sharding.tables.sys_user.table-strategy.complex.sharding-columnsuid, status
spring.shardingsphere.rules.sharding.tables.sys_user.table-strategy.complex.sharding-algorithm-namesys_user_tbl_alg进行新增
Test
public void testAdd(){for (int i 0; i 10; i) {User user new User();user.setUsername(husahng i);user.setPassword(123456);user.setName(name);user.setDescription(描述信息);// 给status也设置值user.setStatus(1);userMapper.insert(user);}
}通过两个分片字段进行查询
Test
public void testComplexInline(){QueryWrapperUser queryWrapper new QueryWrapper();queryWrapper.in(uid, 1026510115563372545L,1026510115626287104L);queryWrapper.eq(status, 0);ListUser users userMapper.selectList(queryWrapper);System.out.println(users);
}CLASS_BASED自定义分片算法
我们可以通过自定义分片算法能够提前判断一些不合理的查询条件。就比如我当前status的值只有0和1如果查询的时候status为3就根本没必要去查询数据库了。
对于complex_inline复杂的分片算法用一个简单的分片表达式也有点不太够用了。
我们可以创建一个java类实现ShardingSphere提供的ComplexKeysShardingAlgorithm接口 自己在java代码中写相应的分片策略 STANDARD- StandardShardingAlgorithm COMPLEX-ComplexKeysShardingAlgorithm 这里就拿复杂的分片策略举例 HINT - HintShardingAlgorithm package com.hs.sharding.algorithm;import com.google.common.collect.Range;
import org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingValue;
import org.apache.shardingsphere.sharding.exception.syntax.UnsupportedShardingOperationException;import java.util.*;/*** 实现自定义COMPLEX分片策略* 声明算法时ComplexKeysShardingAlgorithm接口可传入一个泛型这个泛型就是分片键的数据类型。* 这个泛型只要实现了Comparable接口即可。* 但是官方不建议声明一个明确的泛型出来建议是在doSharding中再做类型转换。这样是为了防止分片键类型与算法声明的类型不符合。* p* 我此时uid就是long status是int 我进行测试** auth roykingw*/
public class MyComplexAlgorithm implements ComplexKeysShardingAlgorithmLong {private Properties props;Overridepublic CollectionString doSharding(CollectionString collection, ComplexKeysShardingValueLong complexKeysShardingValue) {// 假如此时SQL为 select * from sys_user where uid in (xxx,xxx,xxx) and status between {lowerEndpoint} and {upperEndpoint};CollectionLong uidList complexKeysShardingValue.getColumnNameAndShardingValuesMap().get(uid);RangeLong status complexKeysShardingValue.getColumnNameAndRangeValuesMap().get(status);// 拿到status的查询范围if (status ! null) {Long lowerEndpoint status.lowerEndpoint();Long upperEndpoint status.upperEndpoint();if (lowerEndpoint upperEndpoint) {// 如果下限 上限 抛出异常终止去数据库查询的操作throw new UnsupportedShardingOperationException(empty record query, sys_user);} else if (lowerEndpoint 0 || upperEndpoint 1) {// 如果查询范围明显不在status字段的区间中//抛出异常终止去数据库查询的操作throw new UnsupportedShardingOperationException(error range query param, sys_user);}}// 校验都通过后就按照自定义的分片规则来进行分片我这里就按照uid的奇偶来进行ListString result new ArrayList();// 获取逻辑表名 sys_user 而我们的真实表为sys_user1 sys_user2String logicTableName complexKeysShardingValue.getLogicTableName();for (Long uid : uidList) {String resultTableName logicTableName ((uid 1) % 4 /2 1);if (!result.contains(resultTableName)) {result.add(resultTableName);}}return result;}Overridepublic Properties getProps() {return props;}Overridepublic void init(Properties properties) {this.props props;}
}在核心的dosharding方法当中就可以按照我们之前的规则进行判断。不满足规则直接抛出UnsupportedShardingOperationException异常就可以组织ShardingSphere把SQL分配到真实数据库中执行。
接下来还是需要增加策略配置让course表按照这个规则进行分片。
# 使用CLASS_BASED分片算法- 不用配置SPI扩展文件
spring.shardingsphere.rules.sharding.sharding-algorithms.sys_user_tbl_alg.typeCLASS_BASED
# 指定策略 STANDARD|COMPLEX|HINT
spring.shardingsphere.rules.sharding.sharding-algorithms.sys_user_tbl_alg.props.strategyCOMPLEX
# 指定算法实现类。这个类必须是指定的策略对应的算法接口的实现类。
# STANDARD- StandardShardingAlgorithm; COMPLEX-ComplexKeysShardingAlgorithm; HINT - HintShardingAlgorithm
spring.shardingsphere.rules.sharding.sharding-algorithms.sys_user_tbl_alg.props.algorithmClassNamecom.roy.shardingDemo.algorithm.MyComplexAlgorithm此时新增或查询就都会经过上方我们自定义的MyComplexAlgorithm.doSharding()方法来选择具体的分表策略了 HINT_INLINE强制分片算法
使用常见查询虚拟字段的情况HINT强制路由可以用一种与SQL无关的方式进行分库分表。 就比如我仅仅查询uid是奇数的情况如果是单机就可以直接在Mapper接口中添加下面的sql即可
Select(select * from sys_user where MOD(uid,2)1)我们使用ShardingSphere当然也能查询只不过又是全分片路由查询。因为此时我们是根据uid的奇偶来进行分片的所以自然是希望只去查询某一个真实表这种基于虚拟列的查询语句ShardingSphere不知道该去进行解析那么就只能是全路由查询了。
实际上ShardingSphere无法正常解析的语句还有很多。基本上用上分库分表后你的应用就应该要和各种多表关联查询、多层嵌套子查询、distinct查询等各种复杂查询分手了。 这个uid的奇偶关系并不能通过SQL语句正常体现出来这时就需要用上ShardingSphere提供的另外一种分片算法HINT强制路由。HINT强制路由可以用一种与SQL无关的方式进行分库分表。 注释掉之前给course表分配的分表算法重新分配一个HINT_INLINE类型的分表算法
#给sys_user表指定分表策略 sys_user为虚拟表 可以修改 hint-与SQL无关的方式进行分片
spring.shardingsphere.rules.sharding.tables.sys_user.table-strategy.hint.sharding-algorithm-namesys_user_tbl_alg
# 分表策略-HINT用于SQL无关的方式分表使用value关键字。 sys_user_tbl_alg 为自定义string
spring.shardingsphere.rules.sharding.sharding-algorithms.sys_user_tbl_alg.typeHINT_INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.sys_user_tbl_alg.props.algorithm-expressionsys_user$-{value}然后在应用进行查询时使用HintManager给HINT策略指定value的值。
Test
public void queryCourseByHint(){HintManager hintManager HintManager.getInstance();// 强制查sys_user1表hintManager.addTableShardingValue(sys_user,1);try {ListUser users userMapper.selectList(null);System.out.println(users);} finally {//线程安全所有用完要注意关闭。hintManager.close();//hintManager关闭的主要作用是清除ThreadLocal释放内存。HintManager实现了AutoCloseable接口// 所以建议使用try-resource的方式用完自动关闭。//try(HintManager hintManager HintManager.getInstance()){ xxxx }}}注意事项 实体类分片键属性名不要使用idmybatisplus会自动识别id并为它使用雪花算法生成值。如果想使用ShardingSphere的雪花算法生成值就需要注意这个问题 ShardingSphere的雪花算法不是自增长的对它进行取模分片时可能出现数据分片不均匀情况可以自定义雪花算法 不要使用批量插入 insert into course values (1,java,1001,1),(2,java,1001,1);但是这样的SQL语句如果交给ShardingSphere去执行那么这个语句就会造成困惑。到底应该往course_1还是course_2里插入对于这种没有办法正确执行的SQL语句ShardingSphere就会抛出异常。Insert statement does not support sharding table routing to multiple data nodes. 简单inline分片算法默认支持单分片键的 in 精确查询默认情况下不支持范围查询。需要开启一个配置 allow-range-query-with-inline-shardingtrue standard标准分片算法支持精确查询和范围查询 complex_inline 复杂分片算法支持多分片键。但是建议分片键的类型是统一的 class_based自定义分片算法比较灵活可以通过java代码来指定使用的分片逻辑。可以通过实现相应的接口来实现该功能 hint_inline强制分片算法直接在代码中强制指定查询的分片逻辑