com.order.config;
import com.order.dao.RangeShardingTableStrategy;
import com.order.dao.ShardingTableStrategy;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.shardingsphere.api.config.sharding.KeyGeneratorConfiguration;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.apache.shardingsphere.spring.boot.util.DataSourceUtil;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
@Configuration
@MapperScan(basePackages = "com.order.mapper.second", sqlSessionFactoryRef = "secondSqlSessionFactory"
)
public class SecondDataSourceConfig {
// 精确到目录,以便跟其他数据源隔离
static final String MAPPER_LOCATION = "classpath:mapper/second/*.xml"
;
@Value("${spring.shardingsphere.datasource.order.jdbc-url}"
)
private String url;
@Value("${spring.shardingsphere.datasource.order.username}"
)
private String username;
@Value("${spring.shardingsphere.datasource.order.password}"
)
private String password;
/**
* 创建sharding-jdbc的DataSource实例
*
* @return
*/
@Bean(name = "secondDataSource"
)
@Qualifier("secondDataSource"
)
public DataSource shardingDataSource() {
//return DataSourceBuilder.create().build();
return getShardingDataSource();
}
@Bean(name = "secondSqlSessionFactory"
)
public SqlSessionFactory clusterSqlSessionFactory(@Qualifier("secondDataSource"
) DataSource clusterDataSource)
throws Exception {
final SqlSessionFactoryBean sessionFactory =
new SqlSessionFactoryBean();
sessionFactory.setDataSource(clusterDataSource);
sessionFactory.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources(SecondDataSourceConfig.MAPPER_LOCATION));
return sessionFactory.getObject();
}
DataSource getShardingDataSource() {
ShardingRuleConfiguration shardingRuleConfig =
new ShardingRuleConfiguration();
shardingRuleConfig.getTableRuleConfigs().add(getOrderTableRuleConfiguration());
shardingRuleConfig.getBindingTableGroups().add("order_all"
);
//shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("order_id", new ShardingTableStrategy()));
shardingRuleConfig.setDefaultTableShardingStrategyConfig(
new StandardShardingStrategyConfiguration("order_id",
new ShardingTableStrategy(),
new RangeShardingTableStrategy()));
try {
return ShardingDataSourceFactory.createDataSource(createDataSourceMap(), shardingRuleConfig,
new Properties());
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
private static KeyGeneratorConfiguration getKeyGeneratorConfiguration() {
KeyGeneratorConfiguration result =
new KeyGeneratorConfiguration("SNOWFLAKE", "order_id"
);
return result;
}
TableRuleConfiguration getOrderTableRuleConfiguration() {
TableRuleConfiguration result =
new TableRuleConfiguration("order_all", "order.order_all_${0..15}"
);
//result.setKeyGeneratorConfig(getKeyGeneratorConfiguration());
return result;
}
@ConfigurationProperties(prefix = "spring.shardingsphere.datasource.order"
)
Map<String, DataSource>
createDataSourceMap() {
Map<String, DataSource> result =
new HashMap<>
();
// 配置真实数据源
Map<String, Object> dataSourceProperties =
new HashMap<>
();
dataSourceProperties.put("DriverClassName", "com.mysql.jdbc.Driver"
);
dataSourceProperties.put("jdbcUrl"
, url);
dataSourceProperties.put("username"
, username);
dataSourceProperties.put("password"
, password);
try {
DataSource ds = DataSourceUtil.getDataSource("com.zaxxer.hikari.HikariDataSource"
, dataSourceProperties);
result.put("order"
, ds);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
return result;
}
}
为了便于查询,需要设置分表策略,范围查询策略
shardingRuleConfig.setDefaultTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("order_id", new ShardingTableStrategy(),new RangeShardingTableStrategy()))
这里面2个自定义类如下
ShardingTableStrategy
public class ShardingTableStrategy implements PreciseShardingAlgorithm<String> {
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
for (String tableName : collection) {
long divide = Math.abs(preciseShardingValue.getValue().hashCode()) % 16;
if (tableName.endsWith("" + divide)) {
return tableName;
}
}
throw new IllegalArgumentException();
}
}
RangeShardingTableStrategy
public class RangeShardingTableStrategy implements RangeShardingAlgorithm<String> {
@Override
public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<String> rangeShardingValue) {
Collection<String> collect = new ArrayList<>();
for (int i = 0; i < 16; i++) {
for (String each : collection) {
if (each.endsWith(i % collection.size() + "")) {
collect.add(each);
}
}
}
return collect;
}
}
sharding-jdbc多数据源配置分库分表
标签:strategy ISE try ati map ref except apache 分库分表