SpringBoot整合sharding-jdbc?實現(xiàn)分庫分表操作的示例代碼
1、簡介
Sharding-JDBC 是一款開源的分布式數(shù)據(jù)庫中間件,旨在簡化分庫分表(Sharding)的實現(xiàn)。它通過透明化的方式將數(shù)據(jù)分布到多個數(shù)據(jù)庫或表中,同時提供與原生 JDBC 一致的開發(fā)體驗。Sharding-JDBC 是 Apache ShardingSphere 項目的子模塊之一,廣泛應(yīng)用于高并發(fā)、大數(shù)據(jù)量的場景。
核心功能
1、分庫分表:
支持水平分庫和水平分表,將數(shù)據(jù)分散到多個數(shù)據(jù)庫或表中,提升系統(tǒng)性能和存儲能力。
支持多種分片策略,如按范圍、哈希、時間等。
2、讀寫分離:
支持主從架構(gòu)的讀寫分離,將讀操作路由到從庫,寫操作路由到主庫,減輕主庫壓力。
3、分布式事務(wù):
提供基于 XA 和柔性 事務(wù)(Saga、TCC)的分布式事務(wù)支持,確保數(shù)據(jù)一致性。
4、數(shù)據(jù)脫敏:
支持對敏感數(shù)據(jù)進行加密和脫敏處理,保障數(shù)據(jù)安全。
5、多數(shù)據(jù)源管理:
支持動態(tài)數(shù)據(jù)源配置和管理,方便擴展和維護。
6、SQL 兼容性:
支持絕大多數(shù) SQL 語法,兼容主流數(shù)據(jù)庫(如 MySQL、PostgreSQL、Oracle 等)。
核心概念
1、邏輯表(Logic Table):
開發(fā)中使用的虛擬表名,例如 order。
2、真實表(Actual Table):
數(shù)據(jù)庫中實際存在的表,例如 order_0、order_1。
3、數(shù)據(jù)節(jié)點(Data Node):
數(shù)據(jù)分片的最小單元,由數(shù)據(jù)源名稱和真實表組成,例如 ds0.order_0。
4、分片鍵(Sharding Key):
用于分片的字段,例如訂單表中的 user_id。
5、分片算法(Sharding Algorithm):
定義如何根據(jù)分片鍵將數(shù)據(jù)路由到不同的數(shù)據(jù)庫或表。
6、綁定表(Binding Table):
具有相同分片規(guī)則的表,例如 order 和 order_item,可以避免跨表查詢。
架構(gòu)設(shè)計
Sharding-JDBC 采用輕量級的架構(gòu)設(shè)計,直接嵌入應(yīng)用程序中,無需額外部署中間件。其核心組件包括:
SQL 解析引擎:解析 SQL 語句,提取分片鍵。
路由引擎:根據(jù)分片規(guī)則將 SQL 路由到正確的數(shù)據(jù)節(jié)點。
改寫引擎:將邏輯 SQL 改寫為真實 SQL。
執(zhí)行引擎:執(zhí)行 SQL 并合并結(jié)果。
使用場景
1、高并發(fā)場景:
通過分庫分表提升系統(tǒng)的并發(fā)處理能力。
2、大數(shù)據(jù)量場景:
通過數(shù)據(jù)分片解決單表數(shù)據(jù)量過大的問題。
3、讀寫分離場景:
通過讀寫分離提升數(shù)據(jù)庫的讀性能。
4、多租戶場景:
通過分庫分表實現(xiàn)多租戶數(shù)據(jù)隔離。
2、實戰(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); /** * 需要手動配置事務(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è)置分庫策略 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); // 配置第一個數(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"); // 配置第二個數(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; /** * 測試新增 */ @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); } } } /** * 測試更新 */ @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)); } /** * 測試刪除 */ @Test public void testDelete() { orderMapper.delete(new QueryWrapper<>()); } /** * 測試查詢 */ @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 實現(xiàn)分庫分表操作的示例代碼的文章就介紹到這了,更多相關(guān)SpringBoot sharding-jdbc分庫分表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java向Runnable線程傳遞參數(shù)方法實例解析
這篇文章主要介紹了Java向Runnable線程傳遞參數(shù)方法實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06盤點總結(jié)SpringBoot自帶工具類使用提升開發(fā)效率
這篇文章主要為大家介紹了盤點總結(jié)SpringBoot自帶工具類使用提升開發(fā)效率,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12SpringBoot使用MockMvc進行單元測試的實例代碼
在Spring Boot應(yīng)用程序中,使用MockMvc進行單元測試是一種有效的方式,可以驗證控制器的行為和API的正確性,在這篇博客中,我們將介紹如何使用MockMvc對用戶控制器進行測試,感興趣的朋友可以參考下2024-01-01mall整合SpringSecurity及JWT實現(xiàn)認證授權(quán)實戰(zhàn)
這篇文章主要為大家介紹了mall整合SpringSecurity及JWT實現(xiàn)認證授權(quán)實戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06SpringBoot配置數(shù)據(jù)庫密碼加密的方法
由于系統(tǒng)安全的考慮,配置文件中不能出現(xiàn)明文密碼的問題,本文就給大家詳細介紹下springboot配置數(shù)據(jù)庫密碼加密的方法,下面話不多說了,來一起看看詳細的介紹吧,需要的朋友可以參考下2023-08-08java Unicode和UTF-8之間轉(zhuǎn)換實例
這篇文章主要介紹了java Unicode和UTF-8之間轉(zhuǎn)換實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09