spring boot使用sharding jdbc的配置方式
本文介紹了spring boot使用sharding jdbc的配置方式,分享給大家,具體如下:
說明
要排除DataSourceAutoConfiguration,否則多數(shù)據(jù)源無法配置
@SpringBootApplication
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
配置的多個數(shù)據(jù)源交給sharding-jdbc管理,sharding-jdbc創(chuàng)建一個DataSource數(shù)據(jù)源提供給mybatis使用
官方文檔:http://shardingjdbc.io/index_zh.html
步驟
配置多個數(shù)據(jù)源,數(shù)據(jù)源的名稱最好要有一定的規(guī)則,方便配置分庫的計算規(guī)則
@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();
}
配置數(shù)據(jù)源規(guī)則,即將多個數(shù)據(jù)源交給sharding-jdbc管理,并且可以設(shè)置默認的數(shù)據(jù)源,當表沒有配置分庫規(guī)則時會使用默認的數(shù)據(jù)源
@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");
}
配置數(shù)據(jù)源策略和表策略,具體策略需要自己實現(xiàn)
@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();
//綁定表策略,在查詢時會使用主表策略計算路由的數(shù)據(jù)源,因此需要約定綁定表策略的表的規(guī)則需要一致,可以一定程度提高效率
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();
}
創(chuàng)建sharding-jdbc的數(shù)據(jù)源DataSource,MybatisAutoConfiguration會使用此數(shù)據(jù)源
@Bean("dataSource")
public DataSource shardingDataSource(ShardingRule shardingRule){
return ShardingDataSourceFactory.createDataSource(shardingRule);
}
需要手動配置事務(wù)管理器(原因未知)
//需要手動聲明配置事務(wù)
@Bean
public DataSourceTransactionManager transactitonManager(@Qualifier("dataSource") DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
分庫策略的簡單實現(xiàn),接口: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;
}
}
分表策略的基本實現(xiàn),接口: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;
}
}
至此,分庫分表的功能已經(jīng)實現(xiàn)
讀寫分離
讀寫分離需在創(chuàng)建DataSourceRule之前加一層主從數(shù)據(jù)源的創(chuàng)建
// 構(gòu)建讀寫分離數(shù)據(jù)源, 讀寫分離數(shù)據(jù)源實現(xiàn)了DataSource接口, 可直接當做數(shù)據(jù)源處理.
// masterDataSource0, slaveDataSource00, slaveDataSource01等為使用DBCP等連接池配置的真實數(shù)據(jù)源
DataSource masterSlaveDs0 = MasterSlaveDataSourceFactory.createDataSource("ms_0",
masterDataSource0, slaveDataSource00, slaveDataSource01);
DataSource masterSlaveDs1 = MasterSlaveDataSourceFactory.createDataSource("ms_1",
masterDataSource1, slaveDataSource11, slaveDataSource11);
// 構(gòu)建分庫分表數(shù)據(jù)源
Map<String, DataSource> dataSourceMap = new HashMap<>(2);
dataSourceMap.put("ms_0", masterSlaveDs0);
dataSourceMap.put("ms_1", masterSlaveDs1);
// 通過ShardingDataSourceFactory繼續(xù)創(chuàng)建ShardingDataSource
強制使用主庫時
HintManager hintManager = HintManager.getInstance(); hintManager.setMasterRouteOnly(); // 繼續(xù)JDBC操作
強制路由
- 使用ThreadLocal機制實現(xiàn),在執(zhí)行數(shù)據(jù)庫操作之前通過HintManager改變用于計算路由的值
- 設(shè)置HintManager的時候分庫和分表的策略必須同時設(shè)置,并且設(shè)置后需要路由的表都需要設(shè)置用于計算路由的值。比如強制路由后需要操作t_order和t_order_item兩個表,那么兩個表的分庫和分表的策略都需要設(shè)置
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());
事務(wù)
- sharding-jdbc-transaction實現(xiàn)柔性事務(wù)(默認提供了基于內(nèi)存的事務(wù)日志存儲器和內(nèi)嵌異步作業(yè)),可結(jié)合elastic-job(sharding-jdbc-transaction-async-job)實現(xiàn)異步柔性事務(wù)
- 沒有與spring結(jié)合使用的方式,需要自己封裝
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- 詳解springboot采用多數(shù)據(jù)源對JdbcTemplate配置的方法
- springboot2.0.0配置多數(shù)據(jù)源出現(xiàn)jdbcUrl is required with driverClassName的錯誤
- SpringBoot多數(shù)據(jù)源配置詳細教程(JdbcTemplate、mybatis)
- 詳解Springboot之整合JDBCTemplate配置多數(shù)據(jù)源
- springboot+springJdbc+postgresql 實現(xiàn)多數(shù)據(jù)源的配置
- springboot實現(xiàn)以代碼的方式配置sharding-jdbc水平分表
- SpringBoot3+ShardingJDBC5.5.0 讀寫分離配置的實現(xiàn)
- SpringBoot?配置多個JdbcTemplate的實現(xiàn)步驟
- SpringBoot+MybatisPlus+jdbc連接池配置多數(shù)據(jù)源的實現(xiàn)
- Spring?JDBC配置與使用的實現(xiàn)
相關(guān)文章
SpringBoot使用JdbcTemplate訪問操作數(shù)據(jù)庫基本用法
這篇文章主要介紹了SpringBoot使用JdbcTemplate訪問操作數(shù)據(jù)庫基本用法,Spring對數(shù)據(jù)庫的操作在jdbc上s面做了深層次的封裝,使用spring的注入功能,可以把DataSource注冊到JdbcTemplate之中。下文詳細內(nèi)容需要的小伙伴可以參考一下2022-02-02
Oracle+Mybatis的foreach insert批量插入報錯的快速解決辦法
本文給大家介紹Oracle+Mybatis的foreach insert批量插入報錯的快速解決辦法,非常不錯,具有參考借鑒價值,感興趣的朋友參考下吧2016-08-08
SpringMVC中controller接收json數(shù)據(jù)的方法
這篇文章主要為大家詳細介紹了SpringMVC中controller接收json數(shù)據(jù)的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09

