共计 5072 个字符,预计需要花费 13 分钟才能阅读完成。
本文是 Sharding-JDBC 采用 Spring Boot Starter 方式配置第二篇,第一篇是读写分离讲解,请参考:《Spring Boot 中整合 Sharding-JDBC 读写分离示例》
在我《Spring Cloud 微服务 - 全栈技术与案例解析》书中都是通过 XML 方式配置。今天给大家演示的是单库中分表的操作,如果用 XML 方式配置,那么就是下面的配置:
<!– 数据源 –>
<bean id=”ds_0″ class=”com.alibaba.druid.pool.DruidDataSource” destroy-method=”close” primary=”true”>
<property name=”driverClassName” value=”com.mysql.jdbc.Driver” />
<property name=”url” value=”jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8″ />
<property name=”username” value=”root” />
<property name=”password” value=”123456″ />
</bean>
<!– algorithm-class=”com.fangjia.sharding.UserSingleKeyTableShardingAlgorithm” –>
<!– user_0,user_1,user_2,user_3 –>
<rdb:strategy id=”userTableStrategy” sharding-columns=”id” algorithm-expression=”user_${id.longValue() % 4}”/>
<rdb:data-source id=”dataSource”>
<rdb:sharding-rule data-sources=”ds_0″>
<rdb:table-rules>
<rdb:table-rule logic-table=”user” actual-tables=”user_${0..3}” table-strategy=”userTableStrategy”/>
</rdb:table-rules>
<rdb:default-database-strategy sharding-columns=”none” algorithm-class=”com.dangdang.ddframe.rdb.sharding.api.strategy.database.NoneDatabaseShardingAlgorithm”/>
</rdb:sharding-rule>
</rdb:data-source>
我们将 user 表分成了 4 个,分别是 user_0,user_1,user_2,user_3,通过 id 取模的方式决定数据落在哪张表上面。
如果用 Spring Boot 方式配置自然就简单多了,如下:
sharding.jdbc.datasource.names=ds_master
# 数据源
sharding.jdbc.datasource.ds_master.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.ds_master.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.ds_master.url=jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8
sharding.jdbc.datasource.ds_master.username=root
sharding.jdbc.datasource.ds_master.password=123456
# 分表配置
sharding.jdbc.config.sharding.tables.user.actual-data-nodes=ds_master.user_${0..3}
sharding.jdbc.config.sharding.tables.user.table-strategy.inline.sharding-column=id
sharding.jdbc.config.sharding.tables.user.table-strategy.inline.algorithm-expression=user_${id.longValue() % 4}
actual-data-nodes:真实数据节点,由数据源名 + 表名组成,以小数点分隔。多个表以逗号分隔,支持 inline 表达式。
table-strategy.inline.sharding-column:分片字段配置
table-strategy.inline.algorithm-expression:分片算法表达式
自定义分片算法
在 1.x 版本中,单分片算法是通过实现 SingleKeyTableShardingAlgorithm,示例代码如下:
import java.util.Collection;
import java.util.LinkedHashSet;
import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm;
import com.google.common.collect.Range;
public class UserSingleKeyTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm<Long> {
public String doEqualSharding(Collection<String> availableTargetNames, ShardingValue<Long> shardingValue) {
for (String each : availableTargetNames) {
System.out.println(each+”\t”+shardingValue.getValue()+”\t”+shardingValue.getValue() % 4);
if (each.endsWith(shardingValue.getValue() % 4 + “”)) {
return each;
}
}
throw new IllegalArgumentException();
}
public Collection<String> doInSharding(Collection<String> availableTargetNames, ShardingValue<Long> shardingValue) {
Collection<String> result = new LinkedHashSet<>(availableTargetNames.size());
for (Long value : shardingValue.getValues()) {
for (String tableName : availableTargetNames) {
if (tableName.endsWith(value % 4 + “”)) {
result.add(tableName);
}
}
}
return result;
}
public Collection<String> doBetweenSharding(Collection<String> availableTargetNames,
ShardingValue<Long> shardingValue) {
Collection<String> result = new LinkedHashSet<>(availableTargetNames.size());
Range<Long> range = (Range<Long>) shardingValue.getValueRange();
for (Long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
for (String each : availableTargetNames) {
if (each.endsWith(i % 4 + “”)) {
result.add(each);
}
}
}
return result;
}
}
我们这边引入的 Spring Boot Starter 包是 2.x 的版本,在这个版本中,分片算法的接口有调整,我们需要用到标准分片策略 StandardShardingStrategy。提供对 SQL 语句中的 =, IN 和 BETWEEN AND 的分片操作支持。StandardShardingStrategy 只支持单分片键,提供 PreciseShardingAlgorithm 和 RangeShardingAlgorithm 两个分片算法。PreciseShardingAlgorithm 是必选的,用于处理 = 和 IN 的分片。RangeShardingAlgorithm 是可选的,用于处理 BETWEEN AND 分片,如果不配置 RangeShardingAlgorithm,SQL 中的 BETWEEN AND 将按照全库路由处理。
自定义一个单分片算法
import java.util.Collection;
import io.shardingjdbc.core.api.algorithm.sharding.PreciseShardingValue;
import io.shardingjdbc.core.api.algorithm.sharding.standard.PreciseShardingAlgorithm;
/**
* 自定义分片算法
*
* @author yinjihuan
*
*/
public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
@Override
public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
for (String tableName : availableTargetNames) {
if (tableName.endsWith(shardingValue.getValue() % 4 + “”)) {
return tableName;
}
}
throw new IllegalArgumentException();
}
}
使用需要修改我们之前的配置
sharding.jdbc.config.sharding.tables.user.actual-data-nodes=ds_master.user_${0..3}
sharding.jdbc.config.sharding.tables.user.table-strategy.standard.sharding-column=id
sharding.jdbc.config.sharding.tables.user.table-strategy.standard.precise-algorithm-class-name=com.fangjia.sharding.MyPreciseShardingAlgorithm
源码参考:https://github.com/yinjihuan/…
参考代码中测试的代码也写好了,在 Controller 中,启动后通过调用接口的方式测试数据的添加和查询。
另外 Sharding-Sphere 3.0.0.M3 也发布了,新版本看点:1.XA 分布式事务 2. 数据库治理模块增强 3.API 部分调整 4. 修复 M2Bug
项目地址:https://github.com/sharding-s…https://gitee.com/sharding-sp…
一个这么优秀的框架,这么靠谱的研发团队,大家赶紧学起来呀!
欢迎加入我的知识星球,一起交流技术,免费学习猿天地的课程(http://cxytiandi.com/course)