From fdc0ea469a5798ae8089c24b35d4d27ae1e41664 Mon Sep 17 00:00:00 2001 From: Bunny <1319900154@qq.com> Date: Mon, 29 Jul 2024 22:45:55 +0800 Subject: [PATCH] =?UTF-8?q?:rocket:=20feat(=E6=96=B0=E5=A2=9E):=20?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/bunny/entity/order/Order.java | 3 +- .../service/controller/OrderController.java | 13 +++++- .../resources/sharding/sharding-default.yaml | 6 +-- .../resources/sharding/sharding-standard.yaml | 46 +++++++++++++------ .../resources/sharding/sharding-vertical.yaml | 4 +- .../impl/OrderServiceShardingTest.java | 41 ++++++++++++++++- 6 files changed, 90 insertions(+), 23 deletions(-) diff --git a/dao/src/main/java/cn/bunny/entity/order/Order.java b/dao/src/main/java/cn/bunny/entity/order/Order.java index 4e3963a..6d42d47 100644 --- a/dao/src/main/java/cn/bunny/entity/order/Order.java +++ b/dao/src/main/java/cn/bunny/entity/order/Order.java @@ -30,7 +30,8 @@ public class Order implements Serializable { @Serial private static final long serialVersionUID = 1L; - @TableId(value = "id", type = IdType.ASSIGN_ID) + // 当配置shardingSphere雪花算法这里的AUTO会使用shardingSphere的 + @TableId(value = "id", type = IdType.AUTO) private Long id; private String orderNo; diff --git a/service/src/main/java/cn/bunny/service/controller/OrderController.java b/service/src/main/java/cn/bunny/service/controller/OrderController.java index c76940b..96da0fe 100644 --- a/service/src/main/java/cn/bunny/service/controller/OrderController.java +++ b/service/src/main/java/cn/bunny/service/controller/OrderController.java @@ -2,6 +2,7 @@ package cn.bunny.service.controller; import cn.bunny.entity.order.Order; import cn.bunny.pojo.result.Result; +import cn.bunny.service.mapper.OrderMapper; import cn.bunny.service.service.OrderService; import cn.bunny.service.service.UserService; import cn.bunny.vo.page.PageResult; @@ -11,6 +12,8 @@ import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; + /** *

* 前端控制器 @@ -27,6 +30,8 @@ public class OrderController { private OrderService orderService; @Autowired private UserService userService; + @Autowired + private OrderMapper orderMapper; @Operation(summary = "分页查询订单", description = "分页查询订单") @GetMapping("queryPage/{page}/{limit}") @@ -39,7 +44,13 @@ public class OrderController { @Operation(summary = "插入数据", description = "插入数据") @PostMapping("addOrder") public Result addOrder(@RequestBody Order order) { - orderService.save(order); + for (long i = 5; i < 9; i++) { + order = new Order(); + order.setOrderNo("ATGUIGU" + i); + order.setUserId(2L); + order.setAmount(new BigDecimal(100)); + orderMapper.insert(order); + } return Result.success(); } } diff --git a/service/src/main/resources/sharding/sharding-default.yaml b/service/src/main/resources/sharding/sharding-default.yaml index 5248241..b51b474 100644 --- a/service/src/main/resources/sharding/sharding-default.yaml +++ b/service/src/main/resources/sharding/sharding-default.yaml @@ -6,19 +6,19 @@ dataSources: master: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.cj.jdbc.Driver - jdbcUrl: jdbc:mysql://192.168.3.21:3306/db_user?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true + jdbcUrl: jdbc:mysql://192.168.3.98:3306/db_user?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true username: root password: "02120212" slave1: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.cj.jdbc.Driver - jdbcUrl: jdbc:mysql://192.168.3.21:3307/db_user?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true + jdbcUrl: jdbc:mysql://192.168.3.98:3307/db_user?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true username: root password: "02120212" slave2: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.cj.jdbc.Driver - jdbcUrl: jdbc:mysql://192.168.3.21:3308/db_user?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true + jdbcUrl: jdbc:mysql://192.168.3.98:3308/db_user?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true username: root password: "02120212" rules: diff --git a/service/src/main/resources/sharding/sharding-standard.yaml b/service/src/main/resources/sharding/sharding-standard.yaml index 2fddd0c..c7809e8 100644 --- a/service/src/main/resources/sharding/sharding-standard.yaml +++ b/service/src/main/resources/sharding/sharding-standard.yaml @@ -7,23 +7,26 @@ dataSources: server_user: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.cj.jdbc.Driver - jdbcUrl: jdbc:mysql://192.168.3.21:3304/db_user?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true + jdbcUrl: jdbc:mysql://192.168.3.98:3304/db_user?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true username: root password: "02120212" server_order0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.cj.jdbc.Driver - jdbcUrl: jdbc:mysql://192.168.3.21:3300/db_order?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true + jdbcUrl: jdbc:mysql://192.168.3.98:3300/db_order?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true username: root password: "02120212" server_order1: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.cj.jdbc.Driver - jdbcUrl: jdbc:mysql://192.168.3.21:3301/db_order?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true + jdbcUrl: jdbc:mysql://192.168.3.98:3301/db_order?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true username: root password: "02120212" rules: + - !SINGLE + tables: + - "*.*.*" # 数据分片配置 - !SHARDING # 路由表 当表位 t_user 路由到 dataSources为server_user下的t_user @@ -31,7 +34,7 @@ rules: t_user: actualDataNodes: server_user.t_user t_order: - actualDataNodes: server_order${0..1}.t_order{0..1} + actualDataNodes: server_order${0..1}.t_order${0..1} # 指定分片策略--数据库 databaseStrategy: standard: @@ -39,15 +42,29 @@ rules: shardingColumn: user_id # 指定分片算法名称 shardingAlgorithmName: server_order_ds_user_id # server_order_user_id - # 指定分片策略--表 - tableStrategy: - standard: - # 指定分片列字段 - shardingColumn: order_no - # 指定分片算法名称 - shardingAlgorithmName: alg_hash_mod # server_order_user_id + keyGenerateStrategy: + column: id + keyGeneratorName: snowflake + # # 指定分片策略--表 + # tableStrategy: + # standard: + # # 指定分片列字段 + # shardingColumn: order_no + # # 指定分片算法名称 + # shardingAlgorithmName: alg_hash_mod # server_order_user_id - # 分片算法 + autoTables: + t_order: + actualDataSources: server_order${0..1} # 数据源名称 + shardingStrategy: # 切分策略 + standard: # 用于单分片键的标准分片场景 + shardingColumn: order_no # 分片列名称 + shardingAlgorithmName: alg_hash_mod # 自动分片算法名称 + keyGenerateStrategy: + column: id + keyGeneratorName: snowflake + + # 分片算法 shardingAlgorithms: server_order_ds_user_id: type: INLINE @@ -57,8 +74,9 @@ rules: type: HASH_MOD props: sharding-count: 2 - - + keyGenerators: + snowflake: + type: SNOWFLAKE # 打印SQL props: sql-show: true diff --git a/service/src/main/resources/sharding/sharding-vertical.yaml b/service/src/main/resources/sharding/sharding-vertical.yaml index d757725..e445608 100644 --- a/service/src/main/resources/sharding/sharding-vertical.yaml +++ b/service/src/main/resources/sharding/sharding-vertical.yaml @@ -6,13 +6,13 @@ dataSources: server_user: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.cj.jdbc.Driver - jdbcUrl: jdbc:mysql://192.168.3.21:3304/db_user?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true + jdbcUrl: jdbc:mysql://192.168.3.98:3304/db_user?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true username: root password: "02120212" server_order: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.cj.jdbc.Driver - jdbcUrl: jdbc:mysql://192.168.3.21:3305/db_order?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true + jdbcUrl: jdbc:mysql://192.168.3.98:3305/db_order?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true username: root password: "02120212" diff --git a/service/src/test/java/cn/bunny/service/service/impl/OrderServiceShardingTest.java b/service/src/test/java/cn/bunny/service/service/impl/OrderServiceShardingTest.java index 66b204a..33cdd57 100644 --- a/service/src/test/java/cn/bunny/service/service/impl/OrderServiceShardingTest.java +++ b/service/src/test/java/cn/bunny/service/service/impl/OrderServiceShardingTest.java @@ -2,17 +2,22 @@ package cn.bunny.service.service.impl; import cn.bunny.entity.order.Order; import cn.bunny.service.mapper.OrderMapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.util.DigestUtils; import java.math.BigDecimal; +import java.util.List; @SpringBootTest public class OrderServiceShardingTest { @Autowired private OrderMapper orderMapper; + @Autowired + private JdbcTemplate jdbcTemplate; // 水平分片测试 @Test @@ -48,6 +53,7 @@ public class OrderServiceShardingTest { // 分库测试 @Test void testInsertOrderStrategy2() { + for (long i = 4; i < 8; i++) { double random = Math.random(); String md5DigestAsHex = DigestUtils.md5DigestAsHex(String.valueOf(random).getBytes()); @@ -61,11 +67,18 @@ public class OrderServiceShardingTest { } } - // 分库分别测试 + // 分库分别测试,数据库必须要有这个表 生成规则 order_${0..1} @Test void testInsertOrderStrategy3() { - for (long i = 5; i < 9; i++) { + // jdbcTemplate.execute("CREATE TABLE t_order (\n" + + // " id BIGINT,\n" + + // " order_no VARCHAR(30),\n" + + // " user_id BIGINT,\n" + + // " amount DECIMAL(10,2),\n" + + // " PRIMARY KEY(id) USING BTREE\n" + + // ") ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;"); + for (long i = 5; i < 9; i++) { Order order = new Order(); order.setOrderNo("ATGUIGU" + i); order.setUserId(2L); @@ -73,4 +86,28 @@ public class OrderServiceShardingTest { orderMapper.insert(order); } } + + // 会查询所有将数据库自动组装 + @Test + void selectAllOrder1() { + List orders = orderMapper.selectList(null); + orders.forEach(System.out::println); + } + + // 会根据配置规则吗,比如UserId为奇数只会查询配置为奇数的数据库 + @Test + void selectAllOrder2() { + List orders = orderMapper.selectList(Wrappers.lambdaQuery().eq(Order::getUserId, 1L)); + orders.forEach(System.out::println); + } } + +// UUID 不做主键因为无序的, +// 雪花算法是Twitter开源的 +// 有序性:雪花算法生成的ID是有序的,其中包含时间戳信息,因此在一定程度上可以保持生成的ID的有序性,便于数据库索引等操作。 +// 提高索引查询效率 +// 性能:UUID是128位的,相比之下,雪花算法生成的ID长度较短(64位),在存储和索引上更加高效。 +// +// 可读性:雪花算法生成的ID相对于UUID来说,更容易解析和理解,因为其中包含了时间戳等信息,可以直观地看出ID的生成时间。 +// +// 分布式特性:雪花算法考虑了分布式系统中的唯一性要求,通过机器ID和序列号等信息,保证在分布式环境下生成的ID的唯一性。 \ No newline at end of file