spring boot使用sharding jdbc的配置方式
本文介绍了spring boot使用sharding jdbc的配置方式,分享给大家,具体如下: 说明 要排除DataSourceAutoConfiguration,否则多数据源无法配置 @SpringBootApplication @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } } 配置的多个数据源交给sharding-jdbc管理,sharding-jdbc创建一个DataSource数据源提供给mybatis使用 官方文档:http://shardingjdbc.io/index_zh.html 步骤 配置多个数据源,数据源的名称最好要有一定的规则,方便配置分库的计算规则 @Bean(initMethod="init",destroyMethod="close",name="dataSource0") @ConfigurationProperties(prefix = "spring.datasource") public DataSource dataSource0(){ return new DruidDataSource(); } @Bean(initMethod="init",name="dataSource1") @ConfigurationProperties(prefix = "spring.datasource2") public DataSource dataSource1(){ return new DruidDataSource(); } 配置数据源规则,即将多个数据源交给sharding-jdbc管理,并且可以设置默认的数据源,当表没有配置分库规则时会使用默认的数据源 @Bean public DataSourceRule dataSourceRule(@Qualifier("dataSource0") DataSource dataSource0,@Qualifier("dataSource1") DataSource dataSource1){ Map<String,DataSource> dataSourceMap = new HashMap<>(); dataSourceMap.put("dataSource0",dataSource0); dataSourceMap.put("dataSource1",dataSource1); return new DataSourceRule(dataSourceMap,"dataSource0"); } 配置数据源策略和表策略,具体策略需要自己实现 @Bean public ShardingRule shardingRule(DataSourceRule dataSourceRule){ //表策略 TableRule orderTableRule = TableRule.builder("t_order") .actualTables(Arrays.asList("t_order_0","t_order_1")) .tableShardingStrategy(new TableShardingStrategy("order_id",new ModuloTableShardingAlgorithm())) .dataSourceRule(dataSourceRule) .build(); TableRule orderItemTableRule = TableRule.builder("t_order_item") .actualTables(Arrays.asList("t_order_item_0","t_order_item_1")) .tableShardingStrategy(new TableShardingStrategy("order_id",new ModuloTableShardingAlgorithm())) .dataSourceRule(dataSourceRule) .build(); //绑定表策略,在查询时会使用主表策略计算路由的数据源,因此需要约定绑定表策略的表的规则需要一致,可以一定程度提高效率 List<BindingTableRule> bindingTableRules = new ArrayList<BindingTableRule>(); bindingTableRules.add(new BindingTableRule(Arrays.asList(orderTableRule,orderItemTableRule))); return ShardingRule.builder() .dataSourceRule(dataSourceRule) .tableRules(Arrays.asList(orderTableRule,orderItemTableRule)) .bindingTableRules(bindingTableRules) .databaseShardingStrategy(new DatabaseShardingStrategy("user_id",new ModuloDatabaseShardingAlgorithm())) .tableShardingStrategy(new TableShardingStrategy("order_id",new ModuloTableShardingAlgorithm())) .build(); } 创建sharding-jdbc的数据源DataSource,MybatisAutoConfiguration会使用此数据源 @Bean("dataSource") public DataSource shardingDataSource(ShardingRule shardingRule){ return ShardingDataSourceFactory.createDataSource(shardingRule); } 需要手动配置事务管理器(原因未知) //需要手动声明配置事务 @Bean public DataSourceTransactionManager transactitonManager(@Qualifier("dataSource") DataSource dataSource){ return new DataSourceTransactionManager(dataSource); } 分库策略的简单实现,接口:DatabaseShardingAlgorithm import java.util.Collection; import java.util.LinkedHashSet; import com.dangdang.ddframe.rdb.sharding.api.ShardingValue; import com.dangdang.ddframe.rdb.sharding.api.strategy.database.SingleKeyDatabaseShardingAlgorithm; import com.google.common.collect.Range; /** * Created by fuwei.deng on 2017年5月11日. */ public class ModuloDatabaseShardingAlgorithm implements SingleKeyDatabaseShardingAlgorithm<Long> { @Override public String doEqualSharding(Collection<String> databaseNames,ShardingValue<Long> shardingValue) { for (String each : databaseNames) { if (each.endsWith(shardingValue.getValue() % 2 + "")) { return each; } } throw new IllegalArgumentException(); } @Override public Collection<String> doInSharding(Collection<String> databaseNames,ShardingValue<Long> shardingValue) { Collection<String> result = new LinkedHashSet<>(databaseNames.size()); for (Long value : shardingValue.getValues()) { for (String tableName : databaseNames) { if (tableName.endsWith(value % 2 + "")) { result.add(tableName); } } } return result; } @Override public Collection<String> doBetweenSharding(Collection<String> databaseNames,ShardingValue<Long> shardingValue) { Collection<String> result = new LinkedHashSet<>(databaseNames.size()); Range<Long> range = (Range<Long>) shardingValue.getValueRange(); for (Long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) { for (String each : databaseNames) { if (each.endsWith(i % 2 + "")) { result.add(each); } } } return result; } } 分表策略的基本实现,接口:TableShardingAlgorithm 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; /** * Created by fuwei.deng on 2017年5月11日. */ public class ModuloTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm<Long> { @Override public String doEqualSharding(Collection<String> tableNames,ShardingValue<Long> shardingValue) { for (String each : tableNames) { if (each.endsWith(shardingValue.getValue() % 2 + "")) { return each; } } throw new IllegalArgumentException(); } @Override public Collection<String> doInSharding(Collection<String> tableNames,ShardingValue<Long> shardingValue) { Collection<String> result = new LinkedHashSet<>(tableNames.size()); for (Long value : shardingValue.getValues()) { for (String tableName : tableNames) { if (tableName.endsWith(value % 2 + "")) { result.add(tableName); } } } return result; } @Override public Collection<String> doBetweenSharding(Collection<String> tableNames,ShardingValue<Long> shardingValue) { Collection<String> result = new LinkedHashSet<>(tableNames.size()); Range<Long> range = (Range<Long>) shardingValue.getValueRange(); for (Long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) { for (String each : tableNames) { if (each.endsWith(i % 2 + "")) { result.add(each); } } } return result; } } 至此,分库分表的功能已经实现 读写分离 读写分离需在创建DataSourceRule之前加一层主从数据源的创建 // 构建读写分离数据源,读写分离数据源实现了DataSource接口,可直接当做数据源处理. // masterDataSource0,slaveDataSource00,slaveDataSource01等为使用DBCP等连接池配置的真实数据源 DataSource masterSlaveDs0 = MasterSlaveDataSourceFactory.createDataSource("ms_0",masterDataSource0,slaveDataSource01); DataSource masterSlaveDs1 = MasterSlaveDataSourceFactory.createDataSource("ms_1",masterDataSource1,slaveDataSource11,slaveDataSource11); // 构建分库分表数据源 Map<String,DataSource> dataSourceMap = new HashMap<>(2); dataSourceMap.put("ms_0",masterSlaveDs0); dataSourceMap.put("ms_1",masterSlaveDs1); // 通过ShardingDataSourceFactory继续创建ShardingDataSource 强制使用主库时 HintManager hintManager = HintManager.getInstance(); hintManager.setMasterRouteOnly(); // 继续JDBC操作 强制路由
HintManager hintManager = HintManager.getInstance(); hintManager.addDatabaseShardingValue("t_order","user_id",1L); hintManager.addTableShardingValue("t_order","order_id",order.getOrderId()); hintManager.addDatabaseShardingValue("t_order_item",1L); hintManager.addTableShardingValue("t_order_item",order.getOrderId()); 事务
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |