1. 引入依赖:
2. 建立数据表:tabe_0,table_1,table_2...
3. 实现分表算法
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 final class JdbcSharingConfig implements SingleKeyTableShardingAlgorithm
/**
* doEqualSharding =
* @param tableNames 实际物理表名
* @param shardingValue [logicTableName="t_order", columnName="order_id", value=20]
*
* select * from t_order from t_order where order_id = 11
* └── SELECT * FROM t_order_1 WHERE order_id = 11
* select * from t_order from t_order where order_id = 44
* └── SELECT * FROM t_order_0 WHERE order_id = 44
*
* select * from t_order from t_order where order_id = 11
* └── SELECT * FROM t_order_1 WHERE order_id = 11
* select * from t_order from t_order where order_id = 44
* └── SELECT * FROM t_order_0 WHERE order_id = 44
*/
public String doEqualSharding(final Collection
int index = (int)(shardingValue.getValue() % 450);
String indexStr = "";
if(index >= 300)
indexStr = "2";
else if(index >= 150)
indexStr = "1";
else
indexStr = "0";
for (String each : tableNames) {
if (each.endsWith(indexStr)) {
return each;
}
}
throw new IllegalArgumentException();
}
/**
* select * from t_order from t_order where order_id in (11,44)
* ├── SELECT * FROM t_order_0 WHERE order_id IN (11,44)
* └── SELECT * FROM t_order_1 WHERE order_id IN (11,44)
* select * from t_order from t_order where order_id in (11,13,15)
* └── SELECT * FROM t_order_1 WHERE order_id IN (11,13,15)
* select * from t_order from t_order where order_id in (22,24,26)
* └──SELECT * FROM t_order_0 WHERE order_id IN (22,24,26)
*/
@Override
public Collection
Collection
for (Long value : shardingValue.getValues()) {
int index = (int)(value % 450);
String indexStr = "";
if(index >= 450)
indexStr = "2";
else if(index >= 300)
indexStr = "1";
else
indexStr = "0";
for (String tableName : tableNames) {
if (tableName.endsWith(indexStr)) {
result.add(tableName);
}
}
}
return result;
}
/**
* select * from t_order from t_order where order_id between 10 and 20
* ├── SELECT * FROM t_order_0 WHERE order_id BETWEEN 10 AND 20
* └── SELECT * FROM t_order_1 WHERE order_id BETWEEN 10 AND 20
*/
@Override
public Collection
Collection
Range
for (Long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
int index = (int)(i % 450);
String indexStr = "";
if(index >= 450)
indexStr = "2";
else if(index >= 300)
indexStr = "1";
else
indexStr = "0";
for (String each : tableNames) {
if (each.endsWith(indexStr)) {
result.add(each);
}
}
}
return result;
}
4. 配置类:
import com.alibaba.druid.pool.DruidDataSource;
import com.dangdang.ddframe.rdb.sharding.api.ShardingDataSourceFactory;
import com.dangdang.ddframe.rdb.sharding.api.rule.DataSourceRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule;
//import com.dangdang.ddframe.rdb.sharding.api.strategy.database.DatabaseShardingStrategy;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.TableShardingStrategy;
import com.mysql.jdbc.Driver;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class DataSourceConfiguration {
@Value("${database.name}")
private String databaseName;
@Value("${database.user}")
private String username;
@Value("${database.psw}")
private String psw;
@Bean
public DataSource getDataSource() throws SQLException {
return buildDataSource();
}
private DataSource buildDataSource() throws SQLException {
// 设置分库映射
Map
// 添加两个数据库db0,db1到map里
dataSourceMap.put("db0", createDataSource(databaseName, username, psw));
// dataSourceMap.put("db1", createDataSource("db1"));
// 设置默认db为db0,也就是为那些没有配置分库分表策略的指定的默认库
// 如果只有一个库,也就是不需要分库的话,map里只放一个映射就行了,只有一个库时不需要指定默认库,但2个及以上时必须指定默认库,否则那些没有配置策略的表将无法操作数据
DataSourceRule dataSourceRule = new DataSourceRule(dataSourceMap, "db0");
// 设置分表映射,将table_0和table_1两个实际的表映射到table逻辑表
// 0和1两个表是真实的表,table是个虚拟不存在的表,只是供使用。如查询所有数据就是select * from table就能查完0和1表的
TableRule orderTableRule = TableRule.builder("table")
.actualTables(Arrays.asList("table_0", "table_1", "table_2"))
.dataSourceRule(dataSourceRule)
.build();
// 具体分库分表策略,按什么规则来分
ShardingRule shardingRule = ShardingRule.builder()
.dataSourceRule(dataSourceRule)
.tableRules(Arrays.asList(orderTableRule))
// .databaseShardingStrategy(new DatabaseShardingStrategy("id_table", new JdbcSharingConfig()))
.tableShardingStrategy(new TableShardingStrategy("id_table", new JdbcSharingConfig())).build();
DataSource dataSource = ShardingDataSourceFactory.createDataSource(shardingRule);
return dataSource;
}
private static DataSource createDataSource(final String dataSourceName, final String username, final String psw) {
// 使用druid连接数据库
DruidDataSource result = new DruidDataSource();
result.setDriverClassName(Driver.class.getName());
result.setUrl(dataSourceName);
result.setUsername(username);
result.setPassword(psw);
return result;
}
}