网址:https://shardingsphere.apache.org/document/current/cn/overview/
依赖:
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc</artifactId>
<version>3.0.0.M1</version>
</dependency>
两库:database0、database1
两表三份:order_0、order_1、order_2、order_item_0、order_item_1、order_item_2
CREATE TABLE `order_0` (
`order_id` bigint(20) NOT NULL,
`order_sn` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `order_1` (
`order_id` bigint(20) NOT NULL,
`order_sn` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `order_2` (
`order_id` bigint(20) NOT NULL,
`order_sn` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `order_item_0` (
`order_id` bigint(20) NOT NULL,
`order_item_msg` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `order_item_1` (
`order_id` bigint(20) NOT NULL,
`order_item_msg` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `order_item_2` (
`order_id` bigint(20) NOT NULL,
`order_item_msg` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
主要配置如下3步:
1、数据源配置
package com.example.shardingjdbc3.config;
import com.alibaba.druid.pool.DruidDataSource;
import io.shardingsphere.core.api.ShardingDataSourceFactory;
import io.shardingsphere.core.api.config.ShardingRuleConfiguration;
import io.shardingsphere.core.api.config.TableRuleConfiguration;
import io.shardingsphere.core.api.config.strategy.StandardShardingStrategyConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
/**
* 数据源配置
*/
@Configuration
public class DataSourceConfig {
public DataSource dataSource0(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/database0?useUnicode=true&characterEncoding=UTF-8&useSSL=false");
dataSource.setUsername("root");
dataSource.setPassword("Root_123456");
return dataSource;
}
public DataSource dataSource1(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/database1?useUnicode=true&characterEncoding=UTF-8&useSSL=false");
dataSource.setUsername("root");
dataSource.setPassword("Root_123456");
return dataSource;
}
@Bean
public DataSource getShardingDataSource() {
// 配置数据源
Map<String, DataSource> dataSourceMap = new HashMap<>();
dataSourceMap.put("database0", dataSource0());
dataSourceMap.put("database1", dataSource1());
// 分表设置
TableRuleConfiguration orderTableRule = new TableRuleConfiguration();
orderTableRule.setActualDataNodes("database${0..1}.order_${0..2}");
orderTableRule.setLogicTable("order");
orderTableRule.setDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("order_id", new DatabasePR(), new DatabasePR()));
orderTableRule.setTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("order_id", new TablePR(), new TablePR()));
TableRuleConfiguration orderItemTableRule = new TableRuleConfiguration();
orderItemTableRule.setActualDataNodes("database${0..1}.order_item_${0..2}");
orderItemTableRule.setLogicTable("order_item");
orderItemTableRule.setDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("order_id", new DatabasePR(), new DatabasePR()));
orderItemTableRule.setTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("order_id", new TablePR(), new TablePR()));
ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
shardingRuleConfig.getTableRuleConfigs().add(orderTableRule);
shardingRuleConfig.getTableRuleConfigs().add(orderItemTableRule);
// 获取数据源对象
DataSource dataSource = null;
try {
dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new ConcurrentHashMap(), new Properties());
} catch (SQLException e) {
e.printStackTrace();
}
return dataSource;
}
}
2、分库策略
package com.example.shardingjdbc3.config;
import com.google.common.collect.Range;
import io.shardingsphere.core.api.algorithm.sharding.PreciseShardingValue;
import io.shardingsphere.core.api.algorithm.sharding.RangeShardingValue;
import io.shardingsphere.core.api.algorithm.sharding.standard.PreciseShardingAlgorithm;
import io.shardingsphere.core.api.algorithm.sharding.standard.RangeShardingAlgorithm;
import java.util.ArrayList;
import java.util.Collection;
/**
* 数据库分库配置
*/
public class DatabasePR implements PreciseShardingAlgorithm<Long>, RangeShardingAlgorithm<Long> {
/**
*
* @param collection 库名,如:database0、database1
* @param preciseShardingValue 理解为相关的id的值吧
* @return
*/
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) {
for (String each : collection) {
if (each.endsWith((preciseShardingValue.getValue() % 2) + "")) {// 分两个库
return each;
}
}
throw new RuntimeException("xxx");
}
/**
*
* @param collection 库名,如:database0、database1
* @param rangeShardingValue 理解为相关的id的值吧
* @return
*/
@Override
public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Long> rangeShardingValue) {
Collection<String> collect = new ArrayList<>();
Range<Long> valueRange = rangeShardingValue.getValueRange();
for (Long i = valueRange.lowerEndpoint(); i <= valueRange.upperEndpoint(); i++) {
for (String each : collection) {
if (each.endsWith(i % 2 + "")) {// 分两个库
collect.add(each);
}
}
}
return collect;
}
}
3、分表策略
package com.example.shardingjdbc3.config;
import com.google.common.collect.Range;
import io.shardingsphere.core.api.algorithm.sharding.PreciseShardingValue;
import io.shardingsphere.core.api.algorithm.sharding.RangeShardingValue;
import io.shardingsphere.core.api.algorithm.sharding.standard.PreciseShardingAlgorithm;
import io.shardingsphere.core.api.algorithm.sharding.standard.RangeShardingAlgorithm;
import java.util.ArrayList;
import java.util.Collection;
/**
* 分表配置
*/
public class TablePR implements PreciseShardingAlgorithm<Long>, RangeShardingAlgorithm<Long> {
final String orderReg = "order_[0-9]+$";// order匹配
final String orderItemReg = "order_item_[0-9]+$";// order_item匹配
/**
*
* @param collection 表名,如order_0、order_1、order_2
* @param preciseShardingValue 理解为相关的id的值吧
* @return
*/
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) {
for (String each : collection) {
if (each.matches(orderReg)) {// order分表配置
if (each.endsWith(preciseShardingValue.getValue() % 3 + "")) {// 分三个表
return each;
}
}
if (each.matches(orderItemReg)) {// order_item分表配置
if (each.endsWith(preciseShardingValue.getValue() % 3 + "")) {// 分三个表
return each;
}
}
}
throw new RuntimeException("xxx");
}
/**
*
* @param collection 表名,如order_0、order_1、order_2
* @param rangeShardingValue 理解为相关的id的值吧
* @return
*/
@Override
public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Long> rangeShardingValue) {
Collection<String> collect = new ArrayList<>();
Range<Long> valueRange = rangeShardingValue.getValueRange();
for (Long i = valueRange.lowerEndpoint(); i <= valueRange.upperEndpoint(); i++) {
for (String each : collection) {
if (each.matches(orderReg)) {// order分表配置
if (each.endsWith(i % 3 + "")) {
collect.add(each);
}
}
if (each.matches(orderItemReg)) {// order_item分表配置
if (each.endsWith(i % 3 + "")) {
collect.add(each);
}
}
}
}
return collect;
}
}