SpringBoot+MybatisPlus+Mysql+Sharding

网友投稿 398 2022-08-24


SpringBoot+MybatisPlus+Mysql+Sharding

目录一、序言1、组件及版本选择2、预期目标二、代码实现(一)素材准备1、实体类2、Mapper类3、全局配置文件(二)增删查改1、保存数据2、查询列表数据3、分页查询数据4、查询详情5、删除数据6、修改数据三、理论分析1、选择分片列2、扩容

一、序言

在实际业务中,单表http://数据增长较快,很容易达到数据瓶颈,比如单表百万级别数据量。当数据量继续增长时,数据的查询性能即使有索引的帮助下也不尽如意,这时可以引入数据分库分表技术。

本文将基于SpringBoot+MybatisPlus+Sharding-JDBC+mysql实现企业级分库分表。

1、组件及版本选择

SpringBoot 2.6.xMybatisPlus 3.5.0Sharding-JDBC 4.1.1Mysql 5.7.35

2、预期目标

使用上述组件实现分库分表,简化起见只讨论分表技术完成分表后的逻辑表与物理表间的增删查改引入逻辑删除和使用MybatisPlus内置分页技术

完整项目源码访问地址。

二、代码实现

为了简化分表复杂性,专注于分表整体实现,简化分表逻辑:按照UserId的奇偶属性分别进行分表。以订单表这一典型场景为例,一般来说有关订单表,通常具有如下共性行为:

创建订单记录查询XX用户的订单列表查询XX用户的订单列表(分页)查询XX订单详情修改订单状态删除订单(逻辑删除)

接下来通过代码实现上述目标。

(一)素材准备

1、实体类

@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 {

}

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、保存数据

由于依据主键的奇偶属性对原表分表,分表后每张表的数据量是分表前的二分之一。根据需要也可以自定义分表数量(比如10张),新分表后的数据量是不分表前的十分之一。

@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、查询列表数据

查询指定用户的订单列表。

@GetMapping("/list")

public AjaxResNiQHejaPult list(Order order) {

LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(order);

return AjaxResult.success(orderMapper.selectList(wrapper));

}

3、分页查询数据

分页查询指定用户的订单列表

@GetMapping("/page")

public AjaxResult page(Page 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、删除数据

通过订单ID删除订单(逻辑删除)

@DeleteMapping("/delete/{orderId}")

public AjaxResult delete(@PathVariable Long orderId) {

return AjaxResult.success(orderMapper.deleteById(orderId));

}

6、修改数据

修改数据一般涉及部分列,比如修改订单表的订单状态等。

@PutMapping("/edit")

public AjaxResult edit(@RequestBody Order order) {

return AjaxResult.success(orderMapper.updateById(order));

}

三、理论分析

1、选择分片列

选择分片列是经过精心对比后确定的,对于订单类场景,需要频繁以用户ID为查询条件筛选数据,因此将同一个用户的订单数据存放在一起有利于提高查询效率。

2、扩容

当分表后的表数据快速增长,可以预见即将达到瓶颈时,需要对分表进行扩容,扩容以2倍的速率进行,扩容期间需要迁移数据,工作量相对可控。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:python_字段类型转换&类型替换(python字典类型转换成字符串)
下一篇:python_切片(python切片选取的区间范围)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~