1.引入jar
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
<version>4.1.1</version>
</dependency>
2.shardingjdbc配置类
/**
* 设置数据源ds0
*/
@Primary
@Bean(name = "ds0", initMethod = "init", destroyMethod = "close")
public DruidDataSource getDs0Source() throws SQLException {
DruidDataSource dataSourceStudent = new DruidDataSource();
String url = "jdbc:mysql://localhost:3306/ds0?allowMultiQueries=true&useSSL=false";
dataSourceStudent.setDriverClassName("com.mysql.jdbc.Driver");
dataSourceStudent.setUrl(url);
dataSourceStudent.setUsername("root");
dataSourceStudent.setPassword("123456");
dataSourceStudent.setInitialSize(5);
dataSourceStudent.setMaxActive(20);
dataSourceStudent.setMinIdle(10);
dataSourceStudent.setMaxWait(30000);
dataSourceStudent.setFilters("stat,wall");
Properties properties = new Properties();
properties.setProperty("connectTimeout", 2000);
properties.setProperty("socketTimeout", 600000);
dataSourceStudent.setConnectProperties(properties);
return dataSourceStudent;
}
/**
* 设置数据源ds1
*/
@Primary
@Bean(name = "ds1", initMethod = "init", destroyMethod = "close")
public DruidDataSource getDs1Source() throws SQLException {
DruidDataSource dataSourceStudent = new DruidDataSource();
String url = "jdbc:mysql://localhost:3306/ds1?allowMultiQueries=true&useSSL=false";
dataSourceStudent.setDriverClassName("com.mysql.jdbc.Driver");
dataSourceStudent.setUrl(url);
dataSourceStudent.setUsername("root");
dataSourceStudent.setPassword("123456");
dataSourceStudent.setInitialSize(5);
dataSourceStudent.setMaxActive(20);
dataSourceStudent.setMinIdle(10);
dataSourceStudent.setMaxWait(30000);
dataSourceStudent.setFilters("stat,wall");
Properties properties = new Properties();
properties.setProperty("connectTimeout", 2000);
properties.setProperty("socketTimeout", 600000);
dataSourceStudent.setConnectProperties(properties);
return dataSourceStudent;
}
/**
* 分片逻辑名称前缀 shard 分表
*/
@Bean(name = "shardingDataSource")
public DataSource shardingDataSource(@Qualifier("ds0") DruidDataSource ds0, @Qualifier("ds1") DruidDataSource ds1) {
// 获取数据源对象
Properties properties = new Properties();
properties.setProperty("max.connections.size.per.query", "10");
if (devMode.equals("dao-dev")) {
// dev 环境开启此参数
properties.setProperty("sql.show", "true");
}
DataSource dataSource = null;
try {
Map<String, DataSource> targetDataSource = new HashMap<>();
targetDataSource.put("ds0", ds0);
targetDataSource.put("ds1", ds1);
//设置分表规则,订单后两位,路由至00-99,100张表
ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
shardingRuleConfig.getTableRuleConfigs().add(orderRuleConfig());
shardingRuleConfig.getTableRuleConfigs().add(orderItemRuleConfig());
//设置分库规则,订单/2,偶數ds0,奇數ds1
shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("order_id", ShardingDBAlgorithm.DATABASE_SHARDING_ALGORITHM));
//绑定表
shardingRuleConfig.getBindingTableGroups().add("t_order, t_order_item");
//创建sharding数据源
dataSource = ShardingDataSourceFactory.createDataSource(targetDataSource, shardingRuleConfig, properties);
} catch (SQLException e) {
e.printStackTrace();
log.error("MYSQL shardconfig 数据源初始化失败");
}
log.info("MYSQL shardconfig 数据源初始化成功");
return dataSource;
}
/**
* 设置订单表分表规则
*/
private TableRuleConfiguration orderRuleConfig() {
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration("t_order", "ds${0..1}.t_order_${0..1}");
StandardShardingStrategyConfiguration tableRule = new StandardShardingStrategyConfiguration("order_id", new OrderCheckShardingTableAlgorithm());
tableRuleConfig.setTableShardingStrategyConfig(tableRule);
return tableRuleConfig;
}
/**
* 设置订单商品表分表规则
*/
private TableRuleConfiguration orderItemRuleConfig() {
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration("t_order_item", "ds${0..1}.t_order_item_${0..1}");
StandardShardingStrategyConfiguration tableRule = new StandardShardingStrategyConfiguration("order_id", new OrderCheckShardingTableAlgorithm());
tableRuleConfig.setTableShardingStrategyConfig(tableRule);
return tableRuleConfig;
}
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import java.util.Collection;
/**
* @program: financial-accounts-receivables
* @description: 订单分表策略
* @author: xiang.yang
* @create: 2021-01-22 16:20
**/
@Slf4j
public class OrderCheckShardingTableAlgorithm implements PreciseShardingAlgorithm<Long> {
@Override
public String doSharding(Collection<String> tableNames, PreciseShardingValue<Long> shardingValue) {
StringBuilder buf = new StringBuilder();
Long orderId = shardingValue.getValue();
String orderIdStr = orderId.toString();
String orderIdSuffix = orderIdStr.substring(orderIdStr.length() - 2);
String logicTableName = shardingValue.getLogicTableName();
buf.append(logicTableName).append("_").append(orderIdSuffix);
if(tableNames.contains(buf.toString())) {
return buf.toString();
} else {
String errMsg = String.format("取模精确分片策略:没找到与分片键匹配的表名! %s : %s = %s", shardingValue.getLogicTableName(), shardingValue.getColumnName(), shardingValue.getValue());
log.info(errMsg);
throw new UnsupportedOperationException(errMsg);
}
}
}
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import java.util.Collection;
/**
* @program: financial-accounts-receivables
* @description: 分库规则
* @author: xiang.yang
* @create: 2021-01-25 17:23
**/
@Slf4j
public class ShardingDBAlgorithm {
public static final DatabaseShardingAlgorithm DATABASE_SHARDING_ALGORITHM = new DatabaseShardingAlgorithm();
/**
* 分库规则
*/
static class DatabaseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
@Override
public String doSharding(Collection<String> databaseNames, PreciseShardingValue<Long> shardingValue) {
Long orderId = shardingValue.getValue();
long index = orderId % 2;
String dataSource = "ds"+index;
log.info("数据库:{}",dataSource);
return dataSource;
}
}
}