复合分片策略代码如下:
<sharding:complex-strategy id="conplexShardingStrategy" sharding-columns="id" algorithm-class="com.study.algorithm.AdminIdShardingAlgorithm" ></sharding:complex-strategy>
<sharding:data-source id="shardingDataSource">
<!--因为我只有一张表。所以就只需要配置一个dataSource-->
<sharding:sharding-rule data-source-names="dataSource" default-data-source-name="dataSource">
<sharding:table-rules>
<!--logic-tables逻辑表名: 逻辑表名 其实就是 sql 中 写的表名称-->
<sharding:table-rule logic-table="t_manager"
actual-data-nodes="dataSource.t_manager_0,dataSource.t_manager_1"
table-strategy-ref="conplexShardingStrategy" generate-key-column="id"
column-key-generator-class="com.study.algorithm.IdKeyGenerator"/>
</sharding:table-rules>
<sharding:binding-table-rules>
<sharding:binding-table-rule logic-tables="t_manager"/>
</sharding:binding-table-rules>
</sharding:sharding-rule>
<sharding:props>
<prop key="sql.show">true</prop>
</sharding:props>
</sharding:data-source>
AdminIdShardingAlgorithm 复合分片算法代码如下:
package com.study.algorithm;
import com.google.common.collect.Range;
import io.shardingjdbc.core.api.algorithm.sharding.ListShardingValue;
import io.shardingjdbc.core.api.algorithm.sharding.PreciseShardingValue;
import io.shardingjdbc.core.api.algorithm.sharding.RangeShardingValue;
import io.shardingjdbc.core.api.algorithm.sharding.ShardingValue;
import io.shardingjdbc.core.api.algorithm.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import java.util.*;
/**
*/
public class AdminIdShardingAlgorithm implements ComplexKeysShardingAlgorithm {
private Logger logger = Logger.getLogger(getClass());
@Override
public Collection<String> doSharding(Collection<String> availableTargetNames, Collection<ShardingValue> shardingValues) {
Collection<String> routTables = new HashSet<String>();
if (shardingValues != null) {
for (ShardingValue shardingValue : shardingValues) {
// eq in 条件
if (shardingValue instanceof ListShardingValue) {
ListShardingValue listShardingValue = (ListShardingValue) shardingValue;
Collection<Comparable> values = listShardingValue.getValues();
if (values != null) {
Iterator<Comparable> it = values.iterator();
while (it.hasNext()) {
Comparable value = it.next();
String routTable = getRoutTable(shardingValue.getLogicTableName(), value);
if (StringUtils.isNotBlank(routTable)) {
routTables.add(routTable);
}
}
}
// eq 条件
} else if (shardingValue instanceof PreciseShardingValue) {
PreciseShardingValue preciseShardingValue = (PreciseShardingValue) shardingValue;
Comparable value = preciseShardingValue.getValue();
String routTable = getRoutTable(shardingValue.getLogicTableName(), value);
if (StringUtils.isNotBlank(routTable)) {
routTables.add(routTable);
}
// between 条件
} else if (shardingValue instanceof RangeShardingValue) {
RangeShardingValue rangeShardingValue = (RangeShardingValue) shardingValue;
Range<Comparable> valueRange = rangeShardingValue.getValueRange();
Comparable lowerEnd = valueRange.lowerEndpoint();
Comparable upperEnd = valueRange.upperEndpoint();
Collection<String> tables = getRoutTables(shardingValue.getLogicTableName(), lowerEnd, upperEnd);
if (tables != null && tables.size() > 0) {
routTables.addAll(tables);
}
}
if (routTables != null && routTables.size() > 0) {
return routTables;
}
}
}
throw new UnsupportedOperationException();
}
private String getRoutTable(String logicTable, Comparable keyValue) {
Map<String, List<KeyShardingRange>> keyRangeMap = KeyShardingRangeConfig.getKeyRangeMap();
List<KeyShardingRange> keyShardingRanges = keyRangeMap.get(KeyShardingRangeConfig.SHARDING_ID_KEY);
if (keyValue != null && keyShardingRanges != null) {
if (keyValue instanceof Integer) {
keyValue = Long.valueOf(((Integer) keyValue).intValue());
}
for (KeyShardingRange range : keyShardingRanges) {
if (keyValue.compareTo(range.getMin()) >= 0 && keyValue.compareTo(range.getMax()) <= 0) {
return logicTable + range.getTableKey();
}
}
}
return null;
}
private Collection<String> getRoutTables(String logicTable, Comparable lowerEnd, Comparable upperEnd) {
Map<String, List<KeyShardingRange>> keyRangeMap = KeyShardingRangeConfig.getKeyRangeMap();
List<KeyShardingRange> keyShardingRanges = keyRangeMap.get(KeyShardingRangeConfig.SHARDING_CONTENT_ID_KEY);
Set<String> routTables = new HashSet<String>();
if (lowerEnd != null && upperEnd != null && keyShardingRanges != null) {
if (lowerEnd instanceof Integer) {
lowerEnd = Long.valueOf(((Integer) lowerEnd).intValue());
}
if (upperEnd instanceof Integer) {
upperEnd = Long.valueOf(((Integer) upperEnd).intValue());
}
boolean start = false;
for (KeyShardingRange range : keyShardingRanges) {
if (lowerEnd.compareTo(range.getMin()) >= 0 && lowerEnd.compareTo(range.getMax()) <= 0) {
start = true;
}
if (start) {
routTables.add(logicTable + range.getTableKey());
}
if (upperEnd.compareTo(range.getMin()) >= 0 && upperEnd.compareTo(range.getMax()) <= 0) {
break;
}
}
}
return routTables;
}
}
范围 map 如下:
package com.study.algorithm;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* 分片键分布配置
*/
public class KeyShardingRangeConfig {
private static Map<String, List<KeyShardingRange>> keyRangeMap = new LinkedHashMap<String, List<KeyShardingRange>>();
public static final String SHARDING_ID_KEY = "id";
public static final String SHARDING_CONTENT_ID_KEY = "adminId";
public static final String SHARDING_DATE_KEY = "createTime";
static {
List<KeyShardingRange> idRanges = new ArrayList<KeyShardingRange>();
idRanges.add(new KeyShardingRange(0, "_0", 0L, 4000000L));
idRanges.add(new KeyShardingRange(1, "_1", 4000001L, 8000000L));
idRanges.add(new KeyShardingRange(2, "_2", 8000001L, 12000000L));
idRanges.add(new KeyShardingRange(3, "_3", 12000001L, 16000000L));
idRanges.add(new KeyShardingRange(4, "_4", 16000001L, 2000000L));
keyRangeMap.put(SHARDING_ID_KEY, idRanges);
List<KeyShardingRange> contentIdRanges = new ArrayList<KeyShardingRange>();
contentIdRanges.add(new KeyShardingRange(0, "_0", 0L, 4000000L));
contentIdRanges.add(new KeyShardingRange(1, "_1", 4000001L, 8000000L));
contentIdRanges.add(new KeyShardingRange(2, "_2", 8000001L, 12000000L));
contentIdRanges.add(new KeyShardingRange(3, "_3", 12000001L, 16000000L));
contentIdRanges.add(new KeyShardingRange(4, "_4", 16000001L, 2000000L));
keyRangeMap.put(SHARDING_CONTENT_ID_KEY, contentIdRanges);
List<KeyShardingRange> timeRanges = new ArrayList<KeyShardingRange>();
timeRanges.add(new KeyShardingRange("_0", 20170701L, 20171231L));
timeRanges.add(new KeyShardingRange("_1", 20180101L, 20180630L));
timeRanges.add(new KeyShardingRange("_2", 20180701L, 20181231L));
timeRanges.add(new KeyShardingRange("_3", 20190101L, 20190630L));
timeRanges.add(new KeyShardingRange("_4", 20190701L, 20191231L));
keyRangeMap.put(SHARDING_DATE_KEY, timeRanges);
}
public static Map<String, List<KeyShardingRange>> getKeyRangeMap() {
return keyRangeMap;
}
}