diff --git a/pom.xml b/pom.xml
index 66d561096fe27ff9fec675b10fe7c9c06822beef..9707eeea2ed8f019978934710bd7bdde30cf6c51 100644
--- a/pom.xml
+++ b/pom.xml
@@ -121,6 +121,16 @@
redisson-spring-boot-starter
3.23.4
+
+ org.apache.shardingsphere
+ shardingsphere-jdbc-core
+ 5.4.1
+
+
+ org.yaml
+ snakeyaml
+ 1.33
+
diff --git a/xfg-frame-archetype-std-app/pom.xml b/xfg-frame-archetype-std-app/pom.xml
index 4bf649afa6031f572c52025beaa77c94719fc94a..4cf6c37c1698e04c48cd2d29eb4feba6415e9f0f 100644
--- a/xfg-frame-archetype-std-app/pom.xml
+++ b/xfg-frame-archetype-std-app/pom.xml
@@ -78,7 +78,6 @@
converter-gson
2.9.0
-
org.apache.dubbo
dubbo
@@ -95,6 +94,14 @@
org.redisson
redisson-spring-boot-starter
+
+ org.apache.shardingsphere
+ shardingsphere-jdbc-core
+
+
+ org.yaml
+ snakeyaml
+
@@ -151,5 +158,4 @@
-
diff --git a/xfg-frame-archetype-std-app/src/main/resources/application-dev.yml b/xfg-frame-archetype-std-app/src/main/resources/application-dev.yml
index 9abba08839ab102eac3df00be5294bc8932ee4f7..38f3d51fb461466e9c9e8277191024dd4ebf330a 100644
--- a/xfg-frame-archetype-std-app/src/main/resources/application-dev.yml
+++ b/xfg-frame-archetype-std-app/src/main/resources/application-dev.yml
@@ -12,27 +12,15 @@ thread:
block-queue-size: 5000
policy: CallerRunsPolicy
-# 数据库配置;启动时配置数据库资源信息
+# 数据库配置 - sharding-jdbc 分库分表
spring:
datasource:
- username: root
- password: 123456
- url: jdbc:mysql://127.0.0.1:13306/xfg_frame_archetype?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&serverTimezone=UTC&useSSL=true
- driver-class-name: com.mysql.cj.jdbc.Driver
- hikari:
- pool-name: Retail_HikariCP
- minimum-idle: 15 #最小空闲连接数量
- idle-timeout: 180000 #空闲连接存活最大时间,默认600000(10分钟)
- maximum-pool-size: 25 #连接池最大连接数,默认是10
- auto-commit: true #此属性控制从池返回的连接的默认自动提交行为,默认值:true
- max-lifetime: 1800000 #此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
- connection-timeout: 30000 #数据库连接超时时间,默认30秒,即30000
- connection-test-query: SELECT 1
- type: com.zaxxer.hikari.HikariDataSource
+ driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
+ url: jdbc:shardingsphere:classpath:sharding/sharding-jdbc-dev.yaml
-#mybatis:
-# mapper-locations: classpath:/mybatis/mapper/*.xml
-# config-location: classpath:/mybatis/config/mybatis-config.xml
+mybatis:
+ mapper-locations: classpath:/mybatis/mapper/*.xml
+ config-location: classpath:/mybatis/config/mybatis-config.xml
# Redis
redis:
diff --git a/xfg-frame-archetype-std-app/src/main/resources/mybatis/mapper/frame_case_mapper.xml b/xfg-frame-archetype-std-app/src/main/resources/mybatis/mapper/frame_case_mapper.xml
deleted file mode 100644
index 7e2ed513346996e764d31fe0edd9774d780eb880..0000000000000000000000000000000000000000
--- a/xfg-frame-archetype-std-app/src/main/resources/mybatis/mapper/frame_case_mapper.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- INSERT INTO table(a,b,c) VALUES(#{a}, #{b}, #{c})
-
-
-
- UPDATE table SET a = #{a} WHERE b = #{b}
-
-
-
-
-
diff --git a/xfg-frame-archetype-std-app/src/main/resources/mybatis/mapper/user_order_mapper.xml b/xfg-frame-archetype-std-app/src/main/resources/mybatis/mapper/user_order_mapper.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0ad6aa718400f2a0af51c5fa6434c0169340d0a5
--- /dev/null
+++ b/xfg-frame-archetype-std-app/src/main/resources/mybatis/mapper/user_order_mapper.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UPDATE user_order SET order_status = 1 WHERE user_id = #{userId}
+
+
+
+
+
diff --git a/xfg-frame-archetype-std-app/src/main/resources/sharding/sharding-jdbc-dev.yaml b/xfg-frame-archetype-std-app/src/main/resources/sharding/sharding-jdbc-dev.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..859a90eccc3bb86ec245bfec098c4e23b0467642
--- /dev/null
+++ b/xfg-frame-archetype-std-app/src/main/resources/sharding/sharding-jdbc-dev.yaml
@@ -0,0 +1,74 @@
+# https://shardingsphere.apache.org/index_zh.html
+mode:
+ # 运行模式类型。可选配置:内存模式 Memory、单机模式 Standalone、集群模式 Cluster - 目前为单机模式
+ type: Standalone
+
+dataSources:
+ ds_0:
+ dataSourceClassName: com.zaxxer.hikari.HikariDataSource
+ driverClassName: com.mysql.cj.jdbc.Driver
+ jdbcUrl: jdbc:mysql://127.0.0.1:13306/xfg_dev_tech_db_00?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&serverTimezone=UTC&useSSL=true
+ username: root
+ password: 123456
+ connectionTimeoutMilliseconds: 30000
+ idleTimeoutMilliseconds: 60000
+ maxLifetimeMilliseconds: 1800000
+ maxPoolSize: 15
+ minPoolSize: 5
+
+ ds_1:
+ dataSourceClassName: com.zaxxer.hikari.HikariDataSource
+ driverClassName: com.mysql.cj.jdbc.Driver
+ jdbcUrl: jdbc:mysql://127.0.0.1:13306/xfg_dev_tech_db_01?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&serverTimezone=UTC&useSSL=true
+ username: root
+ password: 123456
+ connectionTimeoutMilliseconds: 30000
+ idleTimeoutMilliseconds: 60000
+ maxLifetimeMilliseconds: 1800000
+ maxPoolSize: 15
+ minPoolSize: 5
+
+rules:
+ - !SHARDING
+ # 库的路由
+ defaultDatabaseStrategy:
+ standard:
+ shardingColumn: user_id
+ shardingAlgorithmName: database_inline
+ # 表的路由
+ tables:
+ user_order:
+ actualDataNodes: ds_$->{0..1}.user_order_$->{0..3}
+ tableStrategy:
+ standard:
+ shardingColumn: user_id
+ shardingAlgorithmName: user_order_inline
+ # 路由算法
+ shardingAlgorithms:
+ # 库-路由算法 2是两个库,库的数量。库的数量用哈希模2来计算。
+ database_inline:
+ type: INLINE
+ props:
+ algorithm-expression: ds_$->{Math.abs(user_id.hashCode()) % 2}
+
+ # 表-路由算法 4是一个库里,表的数量。4 - 1 为了获得 011 这样的二进制值。不推荐 user_order_$->{Math.abs(user_id.hashCode()) % 2} 作为表的路由
+ user_order_inline:
+ type: INLINE
+ props:
+ algorithm-expression: user_order_$->{(user_id.hashCode() ^ (user_id.hashCode()) >>> 16) & (4 - 1)}
+
+props:
+ # 是否在日志中打印 SQL。
+ # 打印 SQL 可以帮助开发者快速定位系统问题。日志内容包含:逻辑 SQL,真实 SQL 和 SQL 解析结果。
+ # 如果开启配置,日志将使用 Topic ShardingSphere-SQL,日志级别是 INFO。 false
+ sql-show: true
+ # 是否在日志中打印简单风格的 SQL。false
+ sql-simple: true
+ # 用于设置任务处理线程池的大小。每个 ShardingSphereDataSource 使用一个独立的线程池,同一个 JVM 的不同数据源不共享线程池。
+ executor-size: 20
+ # 查询请求在每个数据库实例中所能使用的最大连接数。1
+ max-connections-size-per-query: 1
+ # 在程序启动和更新时,是否检查分片元数据的结构一致性。
+ check-table-metadata-enabled: false
+ # 在程序启动和更新时,是否检查重复表。false
+ check-duplicate-table-enabled: false
\ No newline at end of file
diff --git a/xfg-frame-archetype-std-app/src/test/java/cn/bugstack/test/infrastructure/persistent/UserOrderTest.java b/xfg-frame-archetype-std-app/src/test/java/cn/bugstack/test/infrastructure/persistent/UserOrderTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..88f8c3488182d8d5d91c6d84fcd4cb93eb0d1f38
--- /dev/null
+++ b/xfg-frame-archetype-std-app/src/test/java/cn/bugstack/test/infrastructure/persistent/UserOrderTest.java
@@ -0,0 +1,76 @@
+package cn.bugstack.test.infrastructure.persistent;
+
+import cn.bugstack.infrastructure.persistent.dao.IUserOrderDao;
+import cn.bugstack.infrastructure.persistent.po.UserOrderPO;
+import com.alibaba.fastjson2.JSON;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * 单元测试
+ * @author Fuzhengwei bugstack.cn @小傅哥
+ */
+@Slf4j
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserOrderTest {
+
+ @Resource
+ private IUserOrderDao userOrderDao;
+
+ @Test
+ public void test_selectByUserId() {
+ List list = userOrderDao.selectByUserId("xfg_FOawiP");
+ log.info("测试结果:{}", JSON.toJSONString(list));
+ }
+
+ @Test
+ public void test_insert() {
+ for (int i = 0; i < 10; i++) {
+ UserOrderPO userOrderPO = UserOrderPO.builder()
+ .userName("小傅哥")
+ .userId("xfg_" + RandomStringUtils.randomAlphabetic(6))
+ .userMobile("+86 13521408***")
+ .sku("13811216")
+ .skuName("《手写MyBatis:渐进式源码实践》")
+ .orderId(RandomStringUtils.randomNumeric(11))
+ .quantity(1)
+ .unitPrice(BigDecimal.valueOf(128))
+ .discountAmount(BigDecimal.valueOf(50))
+ .tax(BigDecimal.ZERO)
+ .totalAmount(BigDecimal.valueOf(78))
+ .orderDate(new Date())
+ .orderStatus(0)
+ .isDelete(0)
+ .uuid(UUID.randomUUID().toString().replace("-", ""))
+ .ipv4("127.0.0.1")
+ .ipv6("2001:0db8:85a3:0000:0000:8a2e:0370:7334".getBytes())
+ .extData("{\"device\": {\"machine\": \"IPhone 14 Pro\", \"location\": \"shanghai\"}}")
+ .build();
+
+ userOrderDao.insert(userOrderPO);
+ }
+ }
+
+ /**
+ * 路由测试
+ */
+ @Test
+ public void test_idx() {
+ for (int i = 0; i < 50; i++) {
+ String user_id = "xfg_" + RandomStringUtils.randomAlphabetic(6);
+ log.info("测试结果 {}", (user_id.hashCode() ^ (user_id.hashCode()) >>> 16) & 3);
+ }
+ }
+
+}
diff --git a/xfg-frame-archetype-std-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IUserOrderDao.java b/xfg-frame-archetype-std-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IUserOrderDao.java
new file mode 100644
index 0000000000000000000000000000000000000000..c2fc16822da29cad880f0dcdcd36963dda519540
--- /dev/null
+++ b/xfg-frame-archetype-std-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IUserOrderDao.java
@@ -0,0 +1,17 @@
+package cn.bugstack.infrastructure.persistent.dao;
+
+import cn.bugstack.infrastructure.persistent.po.UserOrderPO;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+@Mapper
+public interface IUserOrderDao {
+
+ void insert(UserOrderPO userOrderPO);
+
+ void updateOrderStatusByUserId(String userId);
+
+ List selectByUserId(String userId);
+
+}
diff --git a/xfg-frame-archetype-std-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/UserOrderPO.java b/xfg-frame-archetype-std-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/UserOrderPO.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b782aab40373a28e522479e666b7e8a31b867a3
--- /dev/null
+++ b/xfg-frame-archetype-std-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/UserOrderPO.java
@@ -0,0 +1,60 @@
+package cn.bugstack.infrastructure.persistent.po;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class UserOrderPO {
+
+ /** 自增ID */
+ private Long id;
+ /** 用户姓名 */
+ private String userName;
+ /** 用户编号 */
+ private String userId;
+ /** 用户电话 */
+ private String userMobile;
+ /** 商品编号 */
+ private String sku;
+ /** 商品名称 */
+ private String skuName;
+ /** 订单ID */
+ private String orderId;
+ /** 商品数量 */
+ private int quantity;
+ /** 商品价格 */
+ private BigDecimal unitPrice;
+ /** 折扣金额 */
+ private BigDecimal discountAmount;
+ /** 费率金额 */
+ private BigDecimal tax;
+ /** 支付金额 */
+ private BigDecimal totalAmount;
+ /** 订单日期 */
+ private Date orderDate;
+ /** 订单状态 */
+ private int orderStatus;
+ /** 逻辑删单 */
+ private int isDelete;
+ /** 唯一索引 */
+ private String uuid;
+ /** 设备地址 */
+ private String ipv4;
+ /** 设备地址 */
+ private byte[] ipv6;
+ /** 扩展数据 */
+ private String extData;
+ /** 更新时间 */
+ private Date updateTime;
+ /** 创建时间 */
+ private Date createTime;
+
+}