一、环境准备

1.数据库

创建2个库2个表:

  • xdclass_shop_order_0

    • product_order_0
    • product_order_1
    • ad_config
    • product_order_item_0
    • product_order_item_1
  • xdclass_shop_order_1
    • product_order_0
    • product_order_1
    • ad_config
    • product_order_item_0
    • product_order_item_1

数据库脚本:

CREATE TABLE `product_order_0` (
`id` bigint NOT NULL AUTO_INCREMENT,
`out_trade_no` varchar(64) DEFAULT NULL COMMENT '订单唯一标识',
`state` varchar(11) DEFAULT NULL COMMENT 'NEW 未支付订单,PAY已经支付订单,CANCEL超时取消订单',
`create_time` datetime DEFAULT NULL COMMENT '订单生成时间',
`pay_amount` decimal(16,2) DEFAULT NULL COMMENT '订单实际支付价格',
`nickname` varchar(64) DEFAULT NULL COMMENT '昵称',
`user_id` bigint DEFAULT NULL COMMENT '用户id',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; CREATE TABLE `ad_config` (
`id` bigint unsigned NOT NULL COMMENT '主键id',
`config_key` varchar(1024) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '配置key',
`config_value` varchar(1024) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '配置value',
`type` varchar(128) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '类型',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; CREATE TABLE `product_order_item_0` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`product_order_id` bigint DEFAULT NULL COMMENT '订单号',
`product_id` bigint DEFAULT NULL COMMENT '产品id',
`product_name` varchar(128) DEFAULT NULL COMMENT '商品名称',
`buy_num` int DEFAULT NULL COMMENT '购买数量',
`user_id` bigint DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

2.代码工程

1.工程创建

  1. 创建Maven工程,添加相关Maven依赖,
 <properties>
<java.version>1.8</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<spring.boot.version>2.5.5</spring.boot.version>
<mybatisplus.boot.starter.version>3.4.0</mybatisplus.boot.starter.version>
<lombok.version>1.18.16</lombok.version>
<sharding-jdbc.version>4.1.1</sharding-jdbc.version>
<junit.version>4.12</junit.version>
<druid.version>1.1.16</druid.version>
<!--跳过单元测试-->
<skipTests>true</skipTests>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring.boot.version}</version>
<scope>test</scope>
</dependency>
<!--mybatis plus和springboot整合-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatisplus.boot.starter.version}</version>
</dependency>
<!-- mysql数据库 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency> <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<!--<scope>provided</scope>-->
</dependency>
<!-- shardingshpere-jdbc-->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>${sharding-jdbc.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
  1. 添加数据库配置文件,根据配置文件可知,配置了两个数据库ds0,ds1;
spring.application.name=yb-sharding-jdbc
server.port=8080 logging.level.root=INFO
# 打印执行的数据库以及语句
spring.shardingsphere.props.sql.show=true # 数据源 ds0 ds1
spring.shardingsphere.datasource.names=ds0,ds1
# 第一个数据库
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://localhost:3306/ybe_shop_order0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=***** # 第二个数据库
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://localhost:3306/ybe_shop_order1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=*****

2.广播表介绍和配置实战

  1. 添加AdConfigDO实体类和添加ProductOrderDOMapper类
//数据库实体类
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("ad_config")
public class AdConfigDO {
private Long id;
private String configKey;
private String configValue;
private String type;
} //数据库实体配置类
public interface AdConfigMapper extends BaseMapper<AdConfigDO> {
}
  1. 设置ad_config为广播表,如果需要配置多个用 逗号 (,) 分开;设置id为生成算法为雪花算法。配置文件中添加如下代码,
#配置广播表
spring.shardingsphere.sharding.broadcast-tables=ad_config
spring.shardingsphere.sharding.tables.ad_config.key-generator.column=id
spring.shardingsphere.sharding.tables.ad_config.key-generator.type=SNOWFLAKE
  1. 添加测试方法
@Test
public void testSaveAdConfig(){
AdConfigDO adConfigDO = new AdConfigDO();
adConfigDO.setConfigKey("banner");
adConfigDO.setConfigValue("ybe.com");
adConfigDO.setType("ad");
adConfigMapper.insert(adConfigDO);
}
  1. 执行结果,两个数据库的表都进行了更新。如下图

3.绑定表介绍和配置实战

  1. 添加ProductOrderItemDO实体类和添加ProductOrderDOMapper类
//数据库实体类
@Data
@TableName("product_order_item")
@EqualsAndHashCode(callSuper = false)
public class ProductOrderItemDO {
private Long id;
private Long productOrderId;
private Long productId;
private String productName;
private Integer buyNum;
private Long userId;
} //数据库实体配置类
public interface ProductOrderItemMapper extends BaseMapper<ProductOrderItemDO> {
}
  1. 添加配置文件,设置product_order和product_order_ite为广播表,如果需要配置多个需要配置多行,binding-tables是个数据
#配置绑定表
spring.shardingsphere.sharding.binding-tables[0]=product_order,product_order_item
  1. 添加测试方法
@Test
public void testBinding(){
List<Object> objects = productOrderMapper.listProductOrderDetail();
System.out.println(objects);
}
  1. 执行结果:

    • 添加绑定表配置之前,可以看到查询的sql语句,主表和子表是笛卡尔积的关联关系。如下图,

    • 添加绑定表配置之后,可以看到查询的sql语句,主表和子表是一一对应的。如下图,

4.行表达式分片策略 InlineShardingStrategy

  • 只支持【单分片键】使用Groovy的表达式,提供对SQL语句中的 =和IN 的分片操作支持
  • 可以通过简单的配置使用,无需自定义分片算法,从而避免繁琐的Java代码开发
  1. 添加ProductOrderDO实体类和添加ProductOrderDOMapper类
//数据库实体类
@Data
@TableName("product_order")
@EqualsAndHashCode(callSuper = false)
public class ProductOrderDO {
// 不设置Mybatis-plus的主键规则,由sharding-jdbc 设置
private Long id;
private String outTradeNo;
private String state;
private Date createTime;
private Double payAmount;
private String nickname;
private Long userId;
} //数据库实体配置类
public interface ProductOrderMapper extends BaseMapper<ProductOrderDO> { }
  1. 配置文件添加如下代码,
# 指定product_order表的数据分布情况,配置数据节点,行表达式标识符使用 ${...} 或 $->{...},但前者与 Spring 本身的文件占位符冲突,所以在 Spring 环境中建议使用 $->{...}
spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds$->{0..1}.product_order_$->{0..1} #id生成策略
spring.shardingsphere.sharding.tables.product_order.key-generator.column=id
spring.shardingsphere.sharding.tables.product_order.key-generator.type=SNOWFLAKE
#work_id 的设置
spring.shardingsphere.sharding.tables.product_order.key-generator.props.worker.id=1 #配置分库规则
spring.shardingsphere.sharding.tables.product_order.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.product_order.database-strategy.inline.algorithm-expression=ds$->{user_id % 2} #配置分表规则
#指定product_order表的分片策略,分片策略包括【分片键和分片算法】
spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.algorithm-expression=product_order_$->{id % 2}

由配置文件可知,

​ 设置了product_order为逻辑表,设置了它的真实数据节点为ds$->{0..1}.product_order_$->{0..1},使用了表达式$->{...},它表示实际的物理表为:ds0.product_order_0,ds0.product_order_1,ds1.product_order_0,ds1.product_order_1,总共对应了2个库的2个物理表。

​ 设置了product_order表的id计算方式为雪花算法;

​ 设置了product_order表的分库规则,分库规则为 user_id % 2;也就是说会根据user_id % 2的结果确定是ds0库还是ds1库。

​ 设置了product_order表的分表规则,分表规则为 id % 2;也就是说会根据id % 2的结果确定是product_order_0表还是product_order_1表。

  1. 添加测试方法
@Test
public void testSaveProductOrder(){
Random random = new Random();
for (int i = 0 ;i < 10 ; i++){
// id是由配置的雪花算法生成
ProductOrderDO productOrderDO = new ProductOrderDO();
productOrderDO.setCreateTime(new Date());
productOrderDO.setNickname("ybe:"+i);
productOrderDO.setOutTradeNo(UUID.randomUUID().toString().substring(0,32));
productOrderDO.setPayAmount(100.00);
productOrderDO.setState("PAY");
// 随机生成UserId
productOrderDO.setUserId(Long.valueOf(random.nextInt(50)));
productOrderMapper.insert(productOrderDO);
}
}
  1. 执行结果根据不同的user_id 和 id ,生成的表记录插入到了不同的库和表,如下图可以看到数据分散在了两个不同的数据库,以及不同的表中。

5.标准分片策略StandardShardingStrategy

  • 只支持【单分片键】,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法
  • PreciseShardingAlgorithm 精准分片 是必选的,用于处理=和IN的分片
  • RangeShardingAlgorithm 范围分片 是可选的,用于处理BETWEEN AND分片
  • 如果不配置RangeShardingAlgorithm,如果SQL中用了BETWEEN AND语法,则将按照全库路由处理,性能下降
  1. 添加分表配置类CustomTablePreciseShardingAlgorithm
public class CustomTablePreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
/**
* @param collection 数据源集合
* 在分库时值为所有分片库的集合 databaseNames
* 分表时为对应分片库中所有分片表的集合 tablesNames
* @param preciseShardingValue 分片属性,包括
* logicTableName 为逻辑表,
* columnName 分片健(字段),
* value 为从 SQL 中解析出的分片健的值
* @return
*/
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) {
//循环遍历 数据源,根据算法
for (String databaseName : collection) {
String value = preciseShardingValue.getValue() % collection.size() + "";
//value是0,则进入0库表,1则进入1库表
if (databaseName.endsWith(value)) {
return databaseName;
}
}
throw new IllegalArgumentException();
}
}
  1. 添加分库配置类CustomDBPreciseShardingAlgorithm
/**
* @param collection 数据源集合
* 在分库时值为所有分片库的集合 databaseNames
* 分表时为对应分片库中所有分片表的集合 tablesNames
* @param preciseShardingValue 分片属性,包括
* logicTableName 为逻辑表,
* columnName 分片健(字段),
* value 为从 SQL 中解析出的分片健的值
* @return
*/
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) {
for (String databaseName : collection) {
String value = preciseShardingValue.getValue() % collection.size() + "";
//value是0,则进入0库表,1则进入1库表
if (databaseName.endsWith(value)) {
return databaseName;
}
}
throw new IllegalArgumentException();
}
  1. 添加分表范围配置类CustomRangeShardingAlgorithm
public class CustomRangeShardingAlgorithm implements RangeShardingAlgorithm<Long> {
/**
* @param collection 数据源集合
* 在分库时值为所有分片库的集合 databaseNames
* 分表时为对应分片库中所有分片表的集合 tablesNames
* @param rangeShardingValue 分片属性,包括
* logicTableName 为逻辑表,
* columnName 分片健(字段),
* value 为从 SQL 中解析出的分片健的值
* @return
*/
@Override
public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Long> rangeShardingValue) {
Set<String> result = new LinkedHashSet<>();
// between 起始值
Long lower = rangeShardingValue.getValueRange().lowerEndpoint();
// between 结束值
Long upper = rangeShardingValue.getValueRange().upperEndpoint();
// 循环范围计算分库逻辑
for (long i = lower; i <= upper; i++) {
for (String databaseName : collection) {
if (databaseName.endsWith(i % collection.size() + "")) {
result.add(databaseName);
}
}
}
return result;
}
}
  1. 配置文件添加图下代码,
# 分库分片算法
spring.shardingsphere.sharding.tables.product_order.database-strategy.standard.sharding-column=user_id
spring.shardingsphere.sharding.tables.product_order.database-strategy.standard.precise-algorithm-class-name=com.ybe.algorithm.CustomDBPreciseShardingAlgorithm
#精准水平分表下,增加一个范围分片
spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.range-algorithm-class-name=com.ybe.algorithm.CustomRangeShardingAlgorithm # 分表分片健
spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.precise-algorithm-class-name=com.ybe.algorithm.CustomTablePreciseShardingAlgorithm
  1. 添加测试方法
@Test
public void testRand(){
Random random = new Random();
for (int i = 0 ;i < 10 ; i++){
ProductOrderDO productOrderDO = new ProductOrderDO();
productOrderDO.setCreateTime(new Date());
productOrderDO.setNickname("ybe:"+i);
productOrderDO.setOutTradeNo(UUID.randomUUID().toString().substring(0,32));
productOrderDO.setPayAmount(100.00);
productOrderDO.setState("PAY");
productOrderDO.setUserId(Long.valueOf(random.nextInt(50)));
productOrderMapper.insert(productOrderDO);
}
productOrderMapper.selectList(new QueryWrapper<ProductOrderDO>().between("id",1L,1L));
}
  1. 执行结果:1.会根据配置的分库、分表规则进行插入不同的数据库和表;2.范围(between)查询的时候会根据id的范围值查询映射的物理表集合。

6.标准分片策略StandardShardingStrategy

  • 只支持【单分片键】,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法
  • PreciseShardingAlgorithm 精准分片 是必选的,用于处理=和IN的分片
  • RangeShardingAlgorithm 范围分片 是可选的,用于处理BETWEEN AND分片
  • 如果不配置RangeShardingAlgorithm,如果SQL中用了BETWEEN AND语法,则将按照全库路由处理,性能下降

添加分表配置类CustomTablePreciseShardingAlgorithm

public class CustomTablePreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
/**
* @param collection 数据源集合
* 在分库时值为所有分片库的集合 databaseNames
* 分表时为对应分片库中所有分片表的集合 tablesNames
* @param preciseShardingValue 分片属性,包括
* logicTableName 为逻辑表,
* columnName 分片健(字段),
* value 为从 SQL 中解析出的分片健的值
* @return
*/
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) {
//循环遍历 数据源,根据算法
for (String databaseName : collection) {
String value = preciseShardingValue.getValue() % collection.size() + "";
//value是0,则进入0库表,1则进入1库表
if (databaseName.endsWith(value)) {
return databaseName;
}
}
throw new IllegalArgumentException();
}
}

添加分库配置类CustomDBPreciseShardingAlgorithm

/**
* @param collection 数据源集合
* 在分库时值为所有分片库的集合 databaseNames
* 分表时为对应分片库中所有分片表的集合 tablesNames
* @param preciseShardingValue 分片属性,包括
* logicTableName 为逻辑表,
* columnName 分片健(字段),
* value 为从 SQL 中解析出的分片健的值
* @return
*/
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) {
for (String databaseName : collection) {
String value = preciseShardingValue.getValue() % collection.size() + "";
//value是0,则进入0库表,1则进入1库表
if (databaseName.endsWith(value)) {
return databaseName;
}
}
throw new IllegalArgumentException();
}

添加分表范围配置类CustomRangeShardingAlgorithm

public class CustomRangeShardingAlgorithm implements RangeShardingAlgorithm<Long> {
/**
* @param collection 数据源集合
* 在分库时值为所有分片库的集合 databaseNames
* 分表时为对应分片库中所有分片表的集合 tablesNames
* @param rangeShardingValue 分片属性,包括
* logicTableName 为逻辑表,
* columnName 分片健(字段),
* value 为从 SQL 中解析出的分片健的值
* @return
*/
@Override
public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Long> rangeShardingValue) {
Set<String> result = new LinkedHashSet<>();
// between 起始值
Long lower = rangeShardingValue.getValueRange().lowerEndpoint();
// between 结束值
Long upper = rangeShardingValue.getValueRange().upperEndpoint();
// 循环范围计算分库逻辑
for (long i = lower; i <= upper; i++) {
for (String databaseName : collection) {
if (databaseName.endsWith(i % collection.size() + "")) {
result.add(databaseName);
}
}
}
return result;
}
}

添加配置文件

# 分库分片算法
spring.shardingsphere.sharding.tables.product_order.database-strategy.standard.sharding-column=user_id
spring.shardingsphere.sharding.tables.product_order.database-strategy.standard.precise-algorithm-class-name=com.ybe.algorithm.CustomDBPreciseShardingAlgorithm
#精准水平分表下,增加一个范围分片
spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.range-algorithm-class-name=com.ybe.algorithm.CustomRangeShardingAlgorithm # 分表分片健
spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.precise-algorithm-class-name=com.ybe.algorithm.CustomTablePreciseShardingAlgorithm

添加测试方法

@Test
public void testRand(){
Random random = new Random();
for (int i = 0 ;i < 10 ; i++){
ProductOrderDO productOrderDO = new ProductOrderDO();
productOrderDO.setCreateTime(new Date());
productOrderDO.setNickname("ybe:"+i);
productOrderDO.setOutTradeNo(UUID.randomUUID().toString().substring(0,32));
productOrderDO.setPayAmount(100.00);
productOrderDO.setState("PAY");
productOrderDO.setUserId(Long.valueOf(random.nextInt(50)));
productOrderMapper.insert(productOrderDO);
}
productOrderMapper.selectList(new QueryWrapper<ProductOrderDO>().between("id",1L,1L));
}

执行结果:1.会根据配置的分库、分表规则进行插入不同的数据库和表;2.between范围查询的时候会根据id查询映射的物理表集合。

7.复合分片算法ComplexShardingStrategy

  • 提供对SQL语句中的=, IN和BETWEEN AND的分片操作,支持【多分片键】
  • 由于多分片键之间的关系复杂,Sharding-JDBC并未做过多的封装
  • 而是直接将分片键值组合以及分片操作符交于算法接口,全部由应用开发者实现,提供最大的灵活度
  1. 添加分表配置类CustomComplexKeysShardingAlgorithm
public class CustomComplexKeysShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {

    @Override
public Collection<String> doSharding(Collection<String> collection, ComplexKeysShardingValue<Long> complexKeysShardingValue) {
// 得到每个分片健对应的值
Collection<Long> orderIdValues = this.getShardingValue(complexKeysShardingValue, "id");
Collection<Long> userIdValues = this.getShardingValue(complexKeysShardingValue, "user_id"); List<String> shardingSuffix = new ArrayList<>();
// 对两个分片健取模的方式
for (Long userId : userIdValues) {
for (Long orderId : orderIdValues) {
String suffix = userId % 2 + "_" + orderId % 2;
for (String databaseName : collection) {
if (databaseName.endsWith(suffix)) {
shardingSuffix.add(databaseName);
}
}
}
}
return shardingSuffix;
}
/**
* shardingValue 分片属性,包括
* logicTableName 为逻辑表,
* columnNameAndShardingValuesMap 存储多个分片健 包括key-value
* key:分片key,id和user_id
* value:分片value,66和99
*
* @return shardingValues 集合
*/
private Collection<Long> getShardingValue(ComplexKeysShardingValue<Long> shardingValues, final String key) {
Collection<Long> valueSet = new ArrayList<>();
Map<String, Collection<Long>> columnNameAndShardingValuesMap = shardingValues.getColumnNameAndShardingValuesMap(); if (columnNameAndShardingValuesMap.containsKey(key)) {
valueSet.addAll(columnNameAndShardingValuesMap.get(key));
}
return valueSet;
}
  1. 配置文件添加如下代码,多个列的类型必须一样。
# 复合分片算法,order_id,user_id 同时作为分片健
spring.shardingsphere.sharding.tables.product_order.table-strategy.complex.sharding-columns=user_id,id
spring.shardingsphere.sharding.tables.product_order.table-strategy.complex.algorithm-class-name=com.ybe.algorithm.CustomComplexKeysShardingAlgorithm
  1. 添加测试方法
@Test
public void testComplex(){
productOrderMapper.selectList(new QueryWrapper<ProductOrderDO>().eq("id",66L).eq("user_id",99L));
}
  1. 执行结果:1.会根据配置的复合分片算法去查找相关的物理表。

8.Hint分片算法HintShardingStrategy

  • 这种分片策略无需配置文件进行配置分片健,分片健值也不再从 SQL中解析,外部手动指定分片健或分片库,让 SQL在指定的分库、分表中执行
  • 通过Hint代码指定的方式而非SQL解析的方式分片的策略
  • Hint策略会绕过SQL解析的,对于这些比较复杂的需要分片的查询,Hint分片策略性能可能会更好
  • 可以指定sql去某个库某个表进行执行
  1. 添加分表配置类CustomTableHintShardingAlgorithm
public class CustomTableHintShardingAlgorithm implements HintShardingAlgorithm<Long> {
@Override
public Collection<String> doSharding(Collection<String> collection, HintShardingValue<Long> hintShardingValue) {
Collection<String> result = new ArrayList<>();
for (String tableName : collection) {
for (Long shardingValue : hintShardingValue.getValues()) {
if (tableName.endsWith(String.valueOf(shardingValue % collection.size()))) {
result.add(tableName);
}
}
}
return result;
}
}
  1. 添加分库配置类CustomDBHintShardingAlgorithm
public class CustomDBHintShardingAlgorithm implements HintShardingAlgorithm<Long>
{
@Override
public Collection<String> doSharding(Collection<String> collection, HintShardingValue<Long> hintShardingValue) {
Collection<String> result = new ArrayList<>();
for (String dbName : collection) {
for (Long shardingValue : hintShardingValue.getValues()) {
if (dbName.endsWith(String.valueOf(shardingValue % collection.size()))) {
result.add(dbName);
}
}
}
return result;
}
}
  1. 配置文件添加如下代码
# Hint分片算法
spring.shardingsphere.sharding.tables.product_order.table-strategy.hint.algorithm-class-name=com.ybe.algorithm.CustomTableHintShardingAlgorithm
spring.shardingsphere.sharding.tables.product_order.database-strategy.hint.algorithm-class-name=com.ybe.algorithm.CustomDBHintShardingAlgorithm
  1. 添加测试方法
@Test
public void testHint(){
// 清除掉历史的规则
HintManager.clear();
//Hint分片策略必须要使用 HintManager工具类
HintManager hintManager = HintManager.getInstance();
// 设置库的分片健,value用于库分片取模,
hintManager.addDatabaseShardingValue("product_order",4L);
// 设置表的分片健,value用于表分片取模,
hintManager.addTableShardingValue("product_order", 5L);
//对应的value只做查询,不做sql解析
productOrderMapper.selectList(new QueryWrapper<ProductOrderDO>().eq("id", 66L));
}
  1. 执行结果:1.不会解析Sql中的分片键,会把hintManager配置的值作为分片键,在CustomTableHintShardingAlgorithm分片算法的中使用。

ShardingSphere-JDBC实战的更多相关文章

  1. JDBC实战案例--利用jdbc实现的宠物信息管理系统

    一.需求: 利用jdbc实现对宠物的信息进行管理的一套系统 宠物信息:宠物ID,宠物类别,宠物名字,宠物性别,宠物年龄,宠物入库日期 系统完成功能:实现对宠物信息的录入,修改,删除,查询. 二.解决方 ...

  2. spark之JDBC开发(实战)

    一.概述 Spark Core.Spark-SQL与Spark-Streaming都是相同的,编写好之后打成jar包使用spark-submit命令提交到集群运行应用$SPARK_HOME/bin#. ...

  3. 重磅|Apache ShardingSphere 5.0.0 即将正式发布

    Apache ShardingSphere 5.0.0 GA 版在经历 5.0.0-alpha 及 5.0.0-beta 接近两年时间的研发和打磨,终于将在 11 月份与大家正式见面! 11 月 10 ...

  4. JDBC上

    JDBC实战--打通数据库 代码实现: package com.imooc.db; import java.sql.Connection; import java.sql.DriverManager; ...

  5. Apache ShardingSphere 5.1.2 发布|全新驱动 API + 云原生部署,打造高性能数据网关

    在 Apache ShardingSphere 5.1.1 发布后,ShardingSphere 合并了来自全球的团队或个人的累计 1028 个 PR,为大家带来 5.1.2 新版本.该版本在功能.性 ...

  6. MYSQL的Java操作器——JDBC

    MYSQL的Java操作器--JDBC 在学习了Mysql之后,我们就要把Mysql和我们之前所学习的Java所结合起来 而JDBC就是这样一种工具:帮助我们使用Java语言来操作Mysql数据库 J ...

  7. Hibernate学习笔记整理系列-------一、Hibernate简介

    Hibernate的官网:http://hibernate.org/ 1.1 Hibernate框架的作用 Hibernate框架是一个数据访问框架(也叫持久层框架,可将实体对象变成持久对象).通过H ...

  8. SpringCloud微服务实战——搭建企业级开发框架(二十七):集成多数据源+Seata分布式事务+读写分离+分库分表

    读写分离:为了确保数据库产品的稳定性,很多数据库拥有双机热备功能.也就是,第一台数据库服务器,是对外提供增删改业务的生产服务器:第二台数据库服务器,主要进行读的操作. 目前有多种方式实现读写分离,一种 ...

  9. ShardingSphere 集成 CosId 实战

    背景 在软件系统演进过程中,随着业务规模的增长 (TPS/存储容量),我们需要通过集群化部署来分摊计算.存储压力. 应用服务的无状态设计使其具备了伸缩性.在使用 Kubernetes 部署时我们只需要 ...

  10. 综合实战--文件上传系统【JDBC&IO&Socket】

    本文纯属记录第一次实战遇到的坑和知识,如果后边有时间再做整理. 1,先写了个操作数据库的工具类SqlTool,照着JDBC资料打完之后,测试的时候出错了,java.lang.ClassNotFound ...

随机推荐

  1. 很好用的vscode 插件 Open PHP/HTML/JS In Browser 让php文件直接在浏览器打开

    p { font-size: 25px } <body> <h1>安装插件</h1> <img src="https://img2020.cnblo ...

  2. jenkins 流水线自动化部署 手动下载安装插件包

    如果有些插件不能通过可选插件安装,可以进行选择高级并上传插件包,插件包链接地址为:http://updates.jenkins-ci.org/download/plugins/ 同时在高级中可以更换下 ...

  3. BUUCTF-FLAG

    FLAG 16进制打开没看到有什么东西,使用binwalk分离也没看到其他文件,猜测是否使用lsb隐写方式. StegSolve打开 可以看到是压缩包的文件头,save bin保存为zip文件解压 提 ...

  4. SAP Using Text Modules in Adobe Forms

    In this demo we will create an adobe form which displays text in two different languages (English or ...

  5. UiPath Orchestrator安装步骤

    UiPath Orchestrator安装步骤 答案在这 https://rpazj.com/thread-219-1-1.html

  6. 分享|智慧环保-生态文明信息化解决方案(附PDF)

    内容摘要: 生态文明建设被提到前所未有的战略高度,我们既要绿水青山,也要金山银山.宁要绿水青山,不要金山银山,而且绿水青山就是金山银山.要正确处理好经济发展同生态环境保护的关系,牢固树立保护生态环境就 ...

  7. MOEAD实现、基于分解的多目标进化、 切比雪夫方法-(python完整代码)

    确定某点附近的点 答:每个解对应的是一组权重,即子问题,红点附近的四个点,也就是它的邻居怎么确定呢?由权重来确定,算法初始化阶段就确定了每个权重对应的邻居,也就是每个子问题的邻居子问题.权重的邻居通过 ...

  8. ssh-修改ssh服务端口号

    在启动selinux的状态下修改ssh的端口号 0.启动selinux     setenforce 1     getenforce 1.修改sshd_config的Port为2234 查看2234 ...

  9. 【万字长文】从零配置一个vue组件库

    简介 本文会从零开始配置一个monorepo类型的组件库,包括规范化配置.打包配置.组件库文档配置及开发一些提升效率的脚本等,monorepo 不熟悉的话这里一句话介绍一下,就是在一个git仓库里包含 ...

  10. [ARC096C] Everything on It 补题记录

    题目链接 题目大意: 对于集合 \(\{1,2,\dots,n\}\) ,求它的子集族中,有多少个满足: 任意两个子集互不相同: \(1,2,\dots,n\) 都在其中至少出现了 \(2\) 次. ...