SpringBoot整合sharding-jdbc?實(shí)現(xiàn)分庫(kù)分表操作的示例代碼
1、簡(jiǎn)介
Sharding-JDBC 是一款開源的分布式數(shù)據(jù)庫(kù)中間件,旨在簡(jiǎn)化分庫(kù)分表(Sharding)的實(shí)現(xiàn)。它通過透明化的方式將數(shù)據(jù)分布到多個(gè)數(shù)據(jù)庫(kù)或表中,同時(shí)提供與原生 JDBC 一致的開發(fā)體驗(yàn)。Sharding-JDBC 是 Apache ShardingSphere 項(xiàng)目的子模塊之一,廣泛應(yīng)用于高并發(fā)、大數(shù)據(jù)量的場(chǎng)景。
核心功能
1、分庫(kù)分表:
支持水平分庫(kù)和水平分表,將數(shù)據(jù)分散到多個(gè)數(shù)據(jù)庫(kù)或表中,提升系統(tǒng)性能和存儲(chǔ)能力。
支持多種分片策略,如按范圍、哈希、時(shí)間等。
2、讀寫分離:
支持主從架構(gòu)的讀寫分離,將讀操作路由到從庫(kù),寫操作路由到主庫(kù),減輕主庫(kù)壓力。
3、分布式事務(wù):
提供基于 XA 和柔性 事務(wù)(Saga、TCC)的分布式事務(wù)支持,確保數(shù)據(jù)一致性。
4、數(shù)據(jù)脫敏:
支持對(duì)敏感數(shù)據(jù)進(jìn)行加密和脫敏處理,保障數(shù)據(jù)安全。
5、多數(shù)據(jù)源管理:
支持動(dòng)態(tài)數(shù)據(jù)源配置和管理,方便擴(kuò)展和維護(hù)。
6、SQL 兼容性:
支持絕大多數(shù) SQL 語法,兼容主流數(shù)據(jù)庫(kù)(如 MySQL、PostgreSQL、Oracle 等)。
核心概念
1、邏輯表(Logic Table):
開發(fā)中使用的虛擬表名,例如 order。
2、真實(shí)表(Actual Table):
數(shù)據(jù)庫(kù)中實(shí)際存在的表,例如 order_0、order_1。
3、數(shù)據(jù)節(jié)點(diǎn)(Data Node):
數(shù)據(jù)分片的最小單元,由數(shù)據(jù)源名稱和真實(shí)表組成,例如 ds0.order_0。
4、分片鍵(Sharding Key):
用于分片的字段,例如訂單表中的 user_id。
5、分片算法(Sharding Algorithm):
定義如何根據(jù)分片鍵將數(shù)據(jù)路由到不同的數(shù)據(jù)庫(kù)或表。
6、綁定表(Binding Table):
具有相同分片規(guī)則的表,例如 order 和 order_item,可以避免跨表查詢。
架構(gòu)設(shè)計(jì)
Sharding-JDBC 采用輕量級(jí)的架構(gòu)設(shè)計(jì),直接嵌入應(yīng)用程序中,無需額外部署中間件。其核心組件包括:
SQL 解析引擎:解析 SQL 語句,提取分片鍵。
路由引擎:根據(jù)分片規(guī)則將 SQL 路由到正確的數(shù)據(jù)節(jié)點(diǎn)。
改寫引擎:將邏輯 SQL 改寫為真實(shí) SQL。
執(zhí)行引擎:執(zhí)行 SQL 并合并結(jié)果。
使用場(chǎng)景
1、高并發(fā)場(chǎng)景:
通過分庫(kù)分表提升系統(tǒng)的并發(fā)處理能力。
2、大數(shù)據(jù)量場(chǎng)景:
通過數(shù)據(jù)分片解決單表數(shù)據(jù)量過大的問題。
3、讀寫分離場(chǎng)景:
通過讀寫分離提升數(shù)據(jù)庫(kù)的讀性能。
4、多租戶場(chǎng)景:
通過分庫(kù)分表實(shí)現(xiàn)多租戶數(shù)據(jù)隔離。
2、實(shí)戰(zhàn)流程
2.1. pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-boot-demo-sharding-jdbc</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-demo-sharding-jdbc</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.xiaoma</groupId>
<artifactId>spring-boot-demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<finalName>spring-boot-demo-sharding-jdbc</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.2. CustomSnowflakeKeyGenerator.java
package com.xiaoma.sharding.jdbc.config;
import cn.hutool.core.lang.Snowflake;
import io.shardingsphere.core.keygen.KeyGenerator;
public class CustomSnowflakeKeyGenerator implements KeyGenerator {
private Snowflake snowflake;
public CustomSnowflakeKeyGenerator(Snowflake snowflake) {
this.snowflake = snowflake;
}
@Override
public Number generateKey() {
return snowflake.nextId();
}
}
2.3. DataSourceShardingConfig.java
@Configuration
public class DataSourceShardingConfig {
private static final Snowflake snowflake = IdUtil.createSnowflake(1, 1);
/**
* 需要手動(dòng)配置事務(wù)管理器
*/
@Bean
public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "dataSource")
@Primary
public DataSource dataSource() throws SQLException {
ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
// 設(shè)置分庫(kù)策略
shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("user_id", "ds${user_id % 2}"));
// 設(shè)置規(guī)則適配的表
shardingRuleConfig.getBindingTableGroups().add("t_order");
// 設(shè)置分表策略
shardingRuleConfig.getTableRuleConfigs().add(orderTableRule());
shardingRuleConfig.setDefaultDataSourceName("ds0");
shardingRuleConfig.setDefaultTableShardingStrategyConfig(new NoneShardingStrategyConfiguration());
Properties properties = new Properties();
properties.setProperty("sql.show", "true");
return ShardingDataSourceFactory.createDataSource(dataSourceMap(), shardingRuleConfig, new ConcurrentHashMap<>(16), properties);
}
private TableRuleConfiguration orderTableRule() {
TableRuleConfiguration tableRule = new TableRuleConfiguration();
// 設(shè)置邏輯表名
tableRule.setLogicTable("t_order");
// ds${0..1}.t_order_${0..2} 也可以寫成 ds$->{0..1}.t_order_$->{0..1}
tableRule.setActualDataNodes("ds${0..1}.t_order_${0..2}");
tableRule.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id", "t_order_$->{order_id % 3}"));
tableRule.setKeyGenerator(customKeyGenerator());
tableRule.setKeyGeneratorColumnName("order_id");
return tableRule;
}
private Map<String, DataSource> dataSourceMap() {
Map<String, DataSource> dataSourceMap = new HashMap<>(16);
// 配置第一個(gè)數(shù)據(jù)源
HikariDataSource ds0 = new HikariDataSource();
ds0.setDriverClassName("com.mysql.cj.jdbc.Driver");
ds0.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test1?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8");
ds0.setUsername("root");
ds0.setPassword("root");
// 配置第二個(gè)數(shù)據(jù)源
HikariDataSource ds1 = new HikariDataSource();
ds1.setDriverClassName("com.mysql.cj.jdbc.Driver");
ds1.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test2?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8");
ds1.setUsername("root");
ds1.setPassword("root");
dataSourceMap.put("ds0", ds0);
dataSourceMap.put("ds1", ds1);
return dataSourceMap;
}
/**
* 自定義主鍵生成器
*/
private KeyGenerator customKeyGenerator() {
return new CustomSnowflakeKeyGenerator(snowflake);
}
}
2.4. SpringBootDemoShardingJdbcApplicationTests.java
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootDemoShardingJdbcApplicationTests {
@Autowired
private OrderMapper orderMapper;
/**
* 測(cè)試新增
*/
@Test
public void testInsert() {
for (long i = 1; i < 10; i++) {
for (long j = 1; j < 20; j++) {
Order order = Order.builder().userId(i).orderId(j).remark(RandomUtil.randomString(20)).build();
orderMapper.insert(order);
}
}
}
/**
* 測(cè)試更新
*/
@Test
public void testUpdate() {
Order update = new Order();
update.setRemark("修改備注信息");
orderMapper.update(update, Wrappers.<Order>update().lambda().eq(Order::getOrderId, 2).eq(Order::getUserId, 2));
}
/**
* 測(cè)試刪除
*/
@Test
public void testDelete() {
orderMapper.delete(new QueryWrapper<>());
}
/**
* 測(cè)試查詢
*/
@Test
public void testSelect() {
List<Order> orders = orderMapper.selectList(Wrappers.<Order>query().lambda().in(Order::getOrderId, 1, 2));
log.info("【orders】= {}", JSONUtil.toJsonStr(orders));
}
}到此這篇關(guān)于SpringBoot整合sharding-jdbc 實(shí)現(xiàn)分庫(kù)分表操作的示例代碼的文章就介紹到這了,更多相關(guān)SpringBoot sharding-jdbc分庫(kù)分表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot集成Sharding-JDBC實(shí)現(xiàn)分庫(kù)分表方式
- SpringBoot+MybatisPlus實(shí)現(xiàn)sharding-jdbc分庫(kù)分表的示例代碼
- SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分庫(kù)分表
- SpringBoot整合sharding-jdbc實(shí)現(xiàn)自定義分庫(kù)分表的實(shí)踐
- SpringBoot整合sharding-jdbc實(shí)現(xiàn)分庫(kù)分表與讀寫分離的示例
- SpringBoot 2.0 整合sharding-jdbc中間件實(shí)現(xiàn)數(shù)據(jù)分庫(kù)分表
相關(guān)文章
詳解Java是如何通過接口來創(chuàng)建代理并進(jìn)行http請(qǐng)求
今天給大家?guī)淼闹R(shí)是關(guān)于Java的,文章圍繞Java是如何通過接口來創(chuàng)建代理并進(jìn)行http請(qǐng)求展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
springboot中在非bean類中調(diào)用bean的實(shí)現(xiàn)方法
在Spring Boot中,非Bean類調(diào)用Bean方法通常需要通過靜態(tài)方法獲取Bean實(shí)例,然后調(diào)用相應(yīng)的方法,這種方法避免了直接在非Bean類中注入Bean,保持了代碼的簡(jiǎn)潔和可維護(hù)性,通過這種方式,可以在不改變?cè)写a結(jié)構(gòu)的情況下,實(shí)現(xiàn)Bean方法的調(diào)用2025-02-02
java static塊和構(gòu)造函數(shù)的實(shí)例詳解
這篇文章主要介紹了java static塊和構(gòu)造函數(shù)的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握J(rèn)ava static關(guān)鍵字的函數(shù)方法,需要的朋友可以參考下2017-09-09
SpringBoot登錄攔截配置詳解(實(shí)測(cè)可用)
這篇文章主要介紹了SpringBoot登錄攔截配置詳解(實(shí)測(cè)可用),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
Spring:@Async注解和AsyncResult與CompletableFuture使用問題
這篇文章主要介紹了Spring:@Async注解和AsyncResult與CompletableFuture使用問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
基于SpringBoot實(shí)現(xiàn)自動(dòng)裝配返回屬性的設(shè)計(jì)思路
這篇文章主要介紹了基于SpringBoot實(shí)現(xiàn)自動(dòng)裝配返回屬性,這里涉及到的技術(shù)知識(shí)點(diǎn)有注解解析器,為什么用ResponseBodyAdvice這里解析?不在Filter,Interceptors,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2022-03-03
一篇文章帶你復(fù)習(xí)java知識(shí)點(diǎn)
以下簡(jiǎn)單介紹了下我對(duì)于這些java基本知識(shí)點(diǎn)和技術(shù)點(diǎn)的一些看法和心得,這些內(nèi)容都源自于我這些年來使用java的一些總結(jié),希望能夠給你帶來幫助2021-06-06

