背景
在做分表时,需要自定义算法。 这里实现的算法是: 分表字段的 hashCode 取余。
算法
public class UserShardingAlgorithm implements StandardShardingAlgorithm<String> {
public static String type = "USER_SHARDING_STRATEGY";
/**
* 分表数量
*/
private int num;
@Override
public void init(Properties props) {
this.num = Integer.valueOf(props.get("number").toString());
}
@Override
public String getType() {
return type;
}
@Override
public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
String value = shardingValue.getValue();
return shardingValue.getDataNodeInfo().getPrefix() + (value.hashCode() % num);
}
@Override
public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<String> shardingValue) {
return availableTargetNames;
}
}
测试代码
修改下数据库配置,直接运行main 方法就可以。
public static void main(String[] args) throws Exception {
ShardingRuleConfiguration result = new ShardingRuleConfiguration();
// 分表配置
ShardingTableRuleConfiguration shardingTableRuleConfiguration =
new ShardingTableRuleConfiguration("user", "user_read.user_$->{0..1}");
// 分表字段, 分表算法
StandardShardingStrategyConfiguration standardShardingStrategyConfiguration
= new StandardShardingStrategyConfiguration("open_id", UserShardingAlgorithm.type);
shardingTableRuleConfiguration.setTableShardingStrategy(standardShardingStrategyConfiguration);
// 住建 key 生成策略
KeyGenerateStrategyConfiguration keyGenerateStrategyConfiguration =
new KeyGenerateStrategyConfiguration("id", "SNOWFLAKE");
shardingTableRuleConfiguration.setKeyGenerateStrategy(keyGenerateStrategyConfiguration);
result.getTables().add(shardingTableRuleConfiguration);
// key 生成算法的 work_id
Properties properties = new Properties();
properties.put("work_id", new Random().nextInt(1024));
result.getKeyGenerators().put("SNOWFLAKE", new AlgorithmConfiguration("SNOWFLAKE", properties));
Properties userSharding = new Properties();
userSharding.put("strategy", "standard");
userSharding.put("number", 2);
userSharding.put("algorithmClassName", UserShardingAlgorithm.class.getName());
result.getShardingAlgorithms().put(UserShardingAlgorithm.type,
new AlgorithmConfiguration("CLASS_BASED", userSharding));
Map<String, DataSource> map = createDatasource();
// 创建 db
DataSource dataSource =
ShardingSphereDataSourceFactory.createDataSource(map, Lists.newArrayList(result), new Properties());
Connection connection = dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("insert into user (open_id) values (?)");
preparedStatement.setString(1, UUID.randomUUID().toString());
// 执行
int execute = preparedStatement.executeUpdate();
System.out.printf("ShardingJdbcDemo.main: " + execute);
connection.close();
}
private static Map<String, DataSource> createDatasource() {
DruidDataSource druidDataSource = new DruidDataSource();
Map<String, DataSource> objectObjectHashMap = new HashMap<>();
druidDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/user_read?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true");
druidDataSource.setUsername("root");
druidDataSource.setPassword("123456");
druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
objectObjectHashMap.put("user_read", druidDataSource);
return objectObjectHashMap;
}