SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分庫分表
一、序言
在實(shí)際業(yè)務(wù)中,單表數(shù)據(jù)增長較快,很容易達(dá)到數(shù)據(jù)瓶頸,比如單表百萬級別數(shù)據(jù)量。當(dāng)數(shù)據(jù)量繼續(xù)增長時,數(shù)據(jù)的查詢性能即使有索引的幫助下也不盡如意,這時可以引入數(shù)據(jù)分庫分表技術(shù)。
本文將基于SpringBoot+MybatisPlus+Sharding-JDBC+Mysql實(shí)現(xiàn)企業(yè)級分庫分表。
1、組件及版本選擇
- SpringBoot 2.6.x
- MybatisPlus 3.5.0
- Sharding-JDBC 4.1.1
- Mysql 5.7.35
2、預(yù)期目標(biāo)
- 使用上述組件實(shí)現(xiàn)分庫分表,簡化起見只討論分表技術(shù)
- 完成分表后的邏輯表與物理表間的增刪查改
- 引入邏輯刪除和使用MybatisPlus內(nèi)置分頁技術(shù)
完整項(xiàng)目源碼訪問地址。
二、代碼實(shí)現(xiàn)
為了簡化分表復(fù)雜性,專注于分表整體實(shí)現(xiàn),簡化分表邏輯:按照UserId的奇偶屬性分別進(jìn)行分表。以訂單表這一典型場景為例,一般來說有關(guān)訂單表,通常具有如下共性行為:
- 創(chuàng)建訂單記錄
- 查詢XX用戶的訂單列表
- 查詢XX用戶的訂單列表(分頁)
- 查詢XX訂單詳情
- 修改訂單狀態(tài)
- 刪除訂單(邏輯刪除)
接下來通過代碼實(shí)現(xiàn)上述目標(biāo)。
(一)素材準(zhǔn)備
1、實(shí)體類
@Data
@TableName("bu_order")
public class Order {
@TableId
private Long orderId;
private Integer orderType;
private Long userId;
private Double amount;
private Integer orderStatus;
@TableLogic
@JsonIgnore
private Boolean deleted;
}
2、Mapper類
@Mapper
public interface OrderMapper extends BaseMapper<Order> {
}
3、全局配置文件
spring:
config:
use-legacy-processing: true
shardingsphere:
datasource:
ds1:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://127.0.0.1:3306/sharding-jdbc2?serverTimezone=UTC
username: root
password: 123456
names: ds1
props:
sql:
show: true
sharding:
tables:
bu_order:
actual-data-nodes: ds1.bu_order_$->{0..1}
key-generator:
column: order_id
type: SNOWFLAKE
table-strategy:
inline:
algorithm-expression: bu_order_${user_id%2}
sharding-column: user_id
(二)增刪查改
1、保存數(shù)據(jù)
由于依據(jù)主鍵的奇偶屬性對原表分表,分表后每張表的數(shù)據(jù)量是分表前的二分之一。根據(jù)需要也可以自定義分表數(shù)量(比如10張),新分表后的數(shù)據(jù)量是不分表前的十分之一。
@Test
public void addOrders() {
for (long i = 1; i <= 10; i++) {
Order order = new Order();
order.setOrderId(i);
order.setOrderType(RandomUtil.randomEle(Arrays.asList(1, 2)));
order.setUserId(RandomUtil.randomEle(Arrays.asList(101L, 102L, 103L)));
order.setAmount(1000.0 * i);
orderMapper.insert(order);
}
}
2、查詢列表數(shù)據(jù)
查詢指定用戶的訂單列表。
@GetMapping("/list")
public AjaxResult list(Order order) {
LambdaQueryWrapper<Order> wrapper = Wrappers.lambdaQuery(order);
return AjaxResult.success(orderMapper.selectList(wrapper));
}
3、分頁查詢數(shù)據(jù)
分頁查詢指定用戶的訂單列表
@GetMapping("/page")
public AjaxResult page(Page<Order> page, Order order) {
return AjaxResult.success(orderMapper.selectPage(page, Wrappers.lambdaQuery(order)));
}
4、查詢詳情
通過訂單ID查詢訂單詳情。
@GetMapping("/detail/{orderId}")
public AjaxResult detail(@PathVariable Long orderId) {
return AjaxResult.success(orderMapper.selectById(orderId));
}
5、刪除數(shù)據(jù)
通過訂單ID刪除訂單(邏輯刪除)
@DeleteMapping("/delete/{orderId}")
public AjaxResult delete(@PathVariable Long orderId) {
return AjaxResult.success(orderMapper.deleteById(orderId));
}
6、修改數(shù)據(jù)
修改數(shù)據(jù)一般涉及部分列,比如修改訂單表的訂單狀態(tài)等。
@PutMapping("/edit")
public AjaxResult edit(@RequestBody Order order) {
return AjaxResult.success(orderMapper.updateById(order));
}
三、理論分析
1、選擇分片列
選擇分片列是經(jīng)過精心對比后確定的,對于訂單類場景,需要頻繁以用戶ID為查詢條件篩選數(shù)據(jù),因此將同一個用戶的訂單數(shù)據(jù)存放在一起有利于提高查詢效率。
2、擴(kuò)容
當(dāng)分表后的表數(shù)據(jù)快速增長,可以預(yù)見即將達(dá)到瓶頸時,需要對分表進(jìn)行擴(kuò)容,擴(kuò)容以2倍的速率進(jìn)行,擴(kuò)容期間需要遷移數(shù)據(jù),工作量相對可控。
到此這篇關(guān)于SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分庫分表 的文章就介紹到這了,更多相關(guān)SpringBoot分庫分表 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MybatisPlus攔截器如何實(shí)現(xiàn)數(shù)據(jù)表分表
- SpringBoot+MybatisPlus實(shí)現(xiàn)sharding-jdbc分庫分表的示例代碼
- SpringBoot+Mybatis-plus+shardingsphere實(shí)現(xiàn)分庫分表的方案
- Mybatis-Plus集成Sharding-JDBC與Flyway實(shí)現(xiàn)多租戶分庫分表實(shí)戰(zhàn)
- SQL數(shù)據(jù)分表Mybatis?Plus動態(tài)表名優(yōu)方案
- springboot+mybatis-plus基于攔截器實(shí)現(xiàn)分表的示例代碼
- Mybatis-plus使用TableNameHandler分表詳解(附完整示例源碼)
- Spring Boot 集成 Sharding-JDBC + Mybatis-Plus 實(shí)現(xiàn)分庫分表功能
- MyBatis-Plus使用動態(tài)表名分表查詢的實(shí)現(xiàn)
相關(guān)文章
Java設(shè)計模式之模板方法模式Template Method Pattern詳解
在我們實(shí)際開發(fā)中,如果一個方法極其復(fù)雜時,如果我們將所有的邏輯寫在一個方法中,那維護(hù)起來就很困難,要替換某些步驟時都要重新寫,這樣代碼的擴(kuò)展性就很差,當(dāng)遇到這種情況就要考慮今天的主角——模板方法模式2022-11-11
Elasticsearch寫入瓶頸導(dǎo)致skywalking大盤空白
這篇文章主要為大家介紹了Elasticsearch寫入瓶頸導(dǎo)致skywalking大盤空白的解決方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02
SpringSecurity實(shí)現(xiàn)自定義登錄接口的詳細(xì)過程
本文詳細(xì)介紹了如何使用SpringSecurity實(shí)現(xiàn)自定義登錄接口,文章還涉及了對用戶實(shí)體類的增強(qiáng)以滿足詳細(xì)信息的需求,適合需要深入了解和實(shí)現(xiàn)SpringSecurity自定義登錄功能的開發(fā)者,感興趣的朋友跟隨小編一起看看吧2024-10-10
利用Java實(shí)現(xiàn)調(diào)用http請求
在實(shí)際開發(fā)過程中,我們經(jīng)常需要調(diào)用對方提供的接口或測試自己寫的接口是否合適。本文就為大家準(zhǔn)備了幾個java調(diào)用http請求的幾種常見方式,需要的可以參考一下2022-08-08

