本文介紹了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", destroyMethod="close", name="dataSource1")@ConfigurationProperties(prefix = "spring.datasource2")public DataSource dataSource1(){ return new DruidDataSource();}配置數據源規則,即將多個數據源交給sharding-jdbc管理,並且可以設置默認的數據源,當表沒有配置分庫規則時會使用默認的數據源
@Beanpublic 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");}配置數據源策略和表策略,具體策略需要自己實現
@Beanpublic 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);}需要手動配置事務管理器(原因未知)
//需要手動聲明配置事務@Beanpublic 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, slaveDataSource00, 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", "user_id", 1L);hintManager.addTableShardingValue("t_order_item", "order_id", order.getOrderId());事務
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。