支持多分片鍵的復(fù)雜分片策略。
配置參數(shù):complex.sharding-columns 分片鍵(多個);
complex.algorithm-class-name 分片算法實現(xiàn)類架谎。
sql和源碼
https://gitee.com/zhangjijige/shardingjdbc.git
配置
spring:
main:
allow-bean-definition-overriding: true
shardingsphere:
# 參數(shù)配置诸狭,顯示 sql
props:
sql:
show: true
# 配置數(shù)據(jù)源
datasource:
# 數(shù)據(jù)源別名
names: db0, db1, db2, db3
# db1數(shù)據(jù)源信息
db0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_0?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
db1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_1?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
db2:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_2?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
db3:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_3?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
sharding:
tables:
# 邏輯表名
tbl_order:
# 指定數(shù)據(jù)節(jié)點
actual-data-nodes: db$->{0..3}.tbl_order_$->{0..3}
# 分庫策略
database-strategy:
standard:
sharding-column: user_id
precise-algorithm-class-name: com.example.shardingjdbc.sharding.algorithm.DBPreciseShardingAlgorithm
# 分表策略
table-strategy:
complex:
sharding-columns: order_id,user_id
# 復(fù)合分表分片配置類
algorithm-class-name: com.example.shardingjdbc.sharding.algorithm.MyComplexShardingAlgorithm
mybatis:
mapper-locations: classpath:mapper/*.xml
策略類
public class MyComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {
private final static String ORDER_ID = "order_id";
private final static String USER_ID = "user_id";
@Override
public Collection<String> doSharding(Collection<String> availableTargetNames,
ComplexKeysShardingValue<Long> shardingValue) {
Collection<Long> orderIds = getShardingValue(shardingValue, ORDER_ID);
Collection<Long> userIds = getShardingValue(shardingValue, USER_ID);
Set<String> tables = new HashSet<>();
for (Long userId : userIds) {
for (Long orderId : orderIds) {
int index = getIndex(userId, orderId, availableTargetNames);
for (String tableName: availableTargetNames) {
if (tableName.endsWith(String.valueOf(index))) {
tables.add(tableName);
}
}
}
}
return tables;
}
private Collection<Long> getShardingValue(ComplexKeysShardingValue shardingValue, String key) {
Collection<Long> valueList = new ArrayList<>();
Map<String, Collection<Long>> columnNameAndShardingValuesMap =
shardingValue.getColumnNameAndShardingValuesMap();
if (columnNameAndShardingValuesMap.containsKey(key)) {
valueList.addAll(columnNameAndShardingValuesMap.get(key));
}
return valueList;
}
private int getIndex(Long userId, Long orderId, Collection<String> availableTargetNames) {
String userIdStr = String.valueOf(userId);
String orderIdStr = String.valueOf(orderId);
int sum = Integer.parseInt(userIdStr.substring(userIdStr.length() - 1)) + Integer.parseInt(orderIdStr.substring(orderIdStr.length() - 1));
return sum % availableTargetNames.size();
}
}
doSharding方法的入?yún)?/p>
會有疑問doSharding方法中的入?yún)hardingValue是如何獲取數(shù)據(jù)的
這個涉及到源碼,主要是mybatis組裝sql后,shardingjdbc會解析sql,并結(jié)合分片建獲取分片建的數(shù)據(jù),具體可以看源碼方法
org.apache.shardingsphere.core.route.router.sharding.ParsingSQLRouter#route
方法中的
OptimizeResult optimizeResult = OptimizeEngineFactory.newInstance(shardingRule, sqlStatement, parameters, generatedKey.orNull()).optimize();