目录
引读
在上一章我们创建了租户,生成了用户服务模块的代码, 这一章我们将根据商场的业务模型编写订单服务模块。
BUG修复说明:
在上一章中,我们重构了框架代码(框架重构造成的BUG),有另外一个bug漏掉了,请重新拉取最新代码并且编译,删除生成的代码重新生成。
为了更好的服务中国用户,我们今天重新发布了gitee版本(https://gitee.com/kutasms/multienty.git.git)
创建客户
在创建订单服务模块之前,我们需要创建客户信息。
request body:
{
"nickName": "wangdefa",
"sex": 0,
"birthday": null,
"phoneNumber": "13880985300",
"inBlackList": false,
"isMember": false,
"avatarUrl": "",
"memberSourceType": 0,
"growth": 0,
"credit": 0,
"status": "NORMAL",
"tenantId": "1211071336825459910"
}
Postman调试
执行后
数据库中已生成客户数据。
订单服务模块
idea端配置和入口程序
接下来,我们新增订单服务模块
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><parent><groupId>org.example</groupId><artifactId>SaasDemo</artifactId><version>1.0-SNAPSHOT</version></parent>
<artifactId>saasmode-order</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>saasdemo-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
创建saasdemo-order资源文件和目录
V1.0.0__init_ddl.sql
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `saas_trade`
--
DROP TABLE IF EXISTS `saas_trade`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_trade` (
`trade_id` bigint(20) NOT NULL COMMENT '交易编号',
`tenant_id` bigint(20) NOT NULL COMMENT '租户编号',
`customer_id` bigint NOT NULL COMMENT '客户编号',
`total_amount` decimal(12,2) DEFAULT NULL COMMENT '总金额',
`discount_amount` decimal(12,2) DEFAULT NULL COMMENT '优惠金额',
`paid_amount` decimal(12,2) DEFAULT NULL COMMENT '支付金额',
`paid` bit(1) DEFAULT NULL COMMENT '是否已支付',
`order_count` int DEFAULT NULL COMMENT '订单数量',
`refunded_count` int DEFAULT NULL COMMENT '已退款数量',
`status` varchar(32) DEFAULT NULL COMMENT '状态',
`version` bigint DEFAULT NULL COMMENT '乐观锁版本号',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`trade_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='交易';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `saas_order`
--
DROP TABLE IF EXISTS `saas_order`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_order` (
`order_id` bigint(20) NOT NULL COMMENT '订单编号',
`tenant_id` bigint(20) NOT NULL COMMENT '租户编号',
`trade_id` bigint NOT NULL COMMENT '交易编号',
`customer_id` bigint NOT NULL COMMENT '客户编号',
`total_amount` decimal(12,2) DEFAULT NULL COMMENT '总金额',
`discount_amount` decimal(12,2) DEFAULT NULL COMMENT '优惠金额',
`paid_amount` decimal(12,2) DEFAULT NULL COMMENT '支付金额',
`paid` bit(1) DEFAULT NULL COMMENT '是否已支付',
`refunded` bit(1) DEFAULT NULL COMMENT '是否已退款',
`order_type` smallint DEFAULT NULL COMMENT '订单类型',
`status` varchar(32) DEFAULT NULL COMMENT '状态',
`version` bigint DEFAULT NULL COMMENT '乐观锁版本号',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `saas_order_buy_member`
--
DROP TABLE IF EXISTS `saas_order_buy_member`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_order_buy_member` (
`order_id` bigint(20) NOT NULL COMMENT '订单编号',
`tenant_id` bigint(20) NOT NULL COMMENT '租户编号',
`customer_id` bigint NOT NULL COMMENT '客户编号',
`member_id` bigint NOT NULL COMMENT '会员编号',
`member_name` varchar(64) NOT NULL COMMENT '会员名称',
`member_price` decimal(12,2) NOT NULL COMMENT '会员价格',
`quantity` int NOT NULL COMMENT '购买数量',
`status` varchar(32) DEFAULT NULL COMMENT '状态',
`version` bigint DEFAULT NULL COMMENT '乐观锁版本号',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单购买会员';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `saas_order_buy_coupon`
--
DROP TABLE IF EXISTS `saas_order_buy_coupon`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_order_buy_coupon` (
`obc_id` bigint(20) NOT NULL COMMENT '优惠券购买编号',
`order_id` bigint(20) NOT NULL COMMENT '订单编号',
`tenant_id` bigint(20) NOT NULL COMMENT '租户编号',
`customer_id` bigint NOT NULL COMMENT '客户编号',
`coupon_id` bigint NOT NULL COMMENT '优惠券编号',
`coupon_name` varchar(64) NOT NULL COMMENT '优惠券名称',
`coupon_price` decimal(12,2) NOT NULL COMMENT '优惠券价格',
`quantity` int NOT NULL COMMENT '购买数量',
`status` varchar(32) DEFAULT NULL COMMENT '状态',
`version` bigint DEFAULT NULL COMMENT '乐观锁版本号',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`obc_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单购买优惠券';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `saas_order_detail`
--
DROP TABLE IF EXISTS `saas_order_detail`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_order_detail` (
`order_id` bigint(20) NOT NULL COMMENT '订单编号',
`tenant_id` bigint(20) DEFAULT NULL COMMENT '租户编号',
`trade_id` bigint NOT NULL COMMENT '交易编号',
`received` bit(1) DEFAULT NULL COMMENT '是否已收货',
`customer_nick` varchar(32) DEFAULT NULL COMMENT '客户昵称',
`customer_phone` varchar(11) DEFAULT NULL COMMENT '客户手机号',
`coupon_id` bigint DEFAULT NULL COMMENT '优惠券编号',
`activity_id` bigint DEFAULT NULL COMMENT '活动编号',
`activity_type` smallint DEFAULT NULL COMMENT '活动类型',
`version` bigint DEFAULT NULL COMMENT '乐观锁版本号',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单详情';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `saas_order_item`
--
DROP TABLE IF EXISTS `saas_order_item`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_order_item` (
`item_id` bigint NOT NULL COMMENT '订单项编号',
`order_id` bigint DEFAULT NULL COMMENT '订单编号',
`product_id` bigint DEFAULT NULL COMMENT '商品编号',
`sku_id` bigint DEFAULT NULL COMMENT '商品规格编号',
`tenant_id` bigint DEFAULT NULL COMMENT '租户编号',
`product_name` varchar(64) DEFAULT NULL COMMENT '商品名称',
`sku_name` varchar(64) DEFAULT NULL COMMENT '商品规格名称',
`price` decimal(12,2) DEFAULT NULL COMMENT '商品价格',
`quantity` int DEFAULT NULL COMMENT '购买数量',
`total_amount` decimal(12,2) DEFAULT NULL COMMENT '总价',
`diff_amount` decimal(12,2) DEFAULT NULL COMMENT '金额差异',
`image` varchar(128) DEFAULT NULL COMMENT '商品主图',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='订单项';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `saas_order_item_attr`
--
DROP TABLE IF EXISTS `saas_order_item_attr`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_order_item_attr` (
`item_id` bigint(20) NOT NULL COMMENT '订单项编号',
`tenant_id` bigint(20) DEFAULT NULL COMMENT '租户编号',
`name` varchar(32) DEFAULT NULL COMMENT '规格名称',
`value` varchar(128) DEFAULT NULL COMMENT '规格值',
`code_name` varchar(64) DEFAULT NULL COMMENT '规格代码名称',
`code_value` varchar(128) DEFAULT NULL COMMENT '规格代码值',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单项属性';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `saas_pay_log`
--
DROP TABLE IF EXISTS `saas_pay_log`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `saas_pay_log` (
`log_id` bigint NOT NULL COMMENT '支付日志编号',
`customer_id` bigint NOT NULL COMMENT '客户编号',
`tenant_id` bigint DEFAULT NULL COMMENT '租户编号',
`trade_id` bigint DEFAULT NULL COMMENT '交易编号',
`order_id` bigint DEFAULT NULL COMMENT '订单编号',
`amount` decimal(12,2) DEFAULT NULL COMMENT '支付金额',
`describe` varchar(64) DEFAULT NULL COMMENT '描述',
`payer_remark` varchar(64) DEFAULT NULL COMMENT '付款方备注',
`payee_remark` varchar(64) DEFAULT NULL COMMENT '收款方备注',
`out_trade_no` varchar(32) DEFAULT NULL COMMENT '交易号码',
`third_no` varchar(48) DEFAULT NULL COMMENT '第三方交易编号',
`status` varchar(32) DEFAULT NULL COMMENT '状态',
`version` bigint DEFAULT NULL COMMENT '乐观锁版本号',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`log_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='支付日志';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `saas_shopping_cart`
--
DROP TABLE IF EXISTS `saas_shopping_cart`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_shopping_cart` (
`cart_id` bigint(20) NOT NULL COMMENT '购物车编号',
`tenant_id` bigint(20) NOT NULL COMMENT '租户编号',
`product_id` bigint NOT NULL COMMENT '商品编号',
`sku_id` bigint NOT NULL COMMENT '商品规格编号',
`customer_id` bigint NOT NULL COMMENT '客户编号',
`quantity` int DEFAULT NULL COMMENT '数量',
`status` varchar(32) DEFAULT NULL COMMENT '状态',
`version` bigint DEFAULT NULL COMMENT '乐观锁版本号',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`cart_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='购物车';
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
V1.0.1__create_undo_ddl.sql
--
-- Table structure for table `undo_log`
--
DROP TABLE IF EXISTS `undo_log`;
-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
application.yml
spring:
profiles:
active: dev
dubbo.application.logger: slf4j
bootstrap.yml
server:
port: 8877
spring:
application:
name: saasdemo-order
cloud:
nacos:
discovery:
server-addr: nacos.xxxx.com:xxxx
namespace: xxxxx-xxxx-xxxx-xxxxx
username: xxxx
password: xxxxx
config:
server-addr: nacos.xxxx.com:xxxx
namespace: xxxxx-xxxx-xxxx-xxxxx
username: xxxx
password: xxxxx
file-extension: yml
extension-configs[0]:
data-id: shardingsphere-saasdemo-order.yml
group: DEFAULT_GROUP
refresh: true
extension-configs[1]:
data-id: multienty.yml
group: DEFAULT_GROUP
refresh: true
extension-configs[2]:
data-id: redis.yml
group: DEFAULT_GROUP
refresh: true
extension-configs[3]:
data-id: rabbitmq.yml
group: DEFAULT_GROUP
refresh: true
seata:
enabled: true
application-id: seata-server
# 客户端和服务端在同一个事务组; Seata 事务组编号,用于 TC 集群名, 一定要和 config.tx(nacos) 中配置的相同
tx-service-group: tx_order_group
# 自动数据源代理
enable-auto-data-source-proxy: false
# 数据源代理模式(分布式事务方案)
data-source-proxy-mode: AT
service:
vgroup-mapping:
tx_order_group: default
config:
# support: nacos, consul, apollo, zk, etcd3, file
type: nacos
nacos:
server-addr: nacos.xxxx.cn:xxxx
namespace: xxxxx-xxxx-xxxx-xxxxx
group: SEATA_GROUP
username: xxxx
password: xxxx
data-id: seata-server.properties
cluster: default
registry:
# support: nacos, eureka, redis, zk, consul, etcd3, sofa
type: nacos
nacos:
server-addr: nacos.xxxx.cn:xxxx
namespace: xxxxx-xxxx-xxxx-xxxxx
group: SEATA_GROUP
username: xxxx
password: xxxx
# 默认TC集群名
cluster: default
# 服务名,与服务端中registry.conf配置要一致
application: seata-server
context-path:
dubbo:
enabled: true
metadata-report:
address: nacos://xxxxx.com:xxxxx?username=${dubbo.metadata-report.username}&password=${dubbo.metadata-report.password}
username: xxxxx
password: xxxxxx
parameters:
namespace: 273e34a2-bc14-41bd-ac55-b8ab8ba27e4a
retry-times: 30 #重试次数,默认100
cycle-report: false #关闭定时刷新
application:
name: order-provider
# 禁用QOS同一台机器可能会有端口冲突现象
qos-enable: false
qos-accept-foreign-ip: false
service-discovery:
migration: FORCE_APPLICATION # FORCE_APPLICATION,只消费应用级地址,如无地址则报错,单订阅 3.x 地址
protocol:
name: dubbo
port: -1
scan:
base-packages: org.example.saas.order.dubbo.service.impl
cloud:
subscribed-services: saasdemo-user, saasdemo-master
registry:
address: nacos://xxxxx.com:xxxxx?username=${dubbo.metadata-report.username}&password=${dubbo.metadata-report.password}
parameters:
namespace: 273e34a2-bc14-41bd-ac55-b8ab8ba27e4a
consumer:
check: false
OrderApplication
添加程序入口
OrderApplication
package org.example.saas.order;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@EnableDiscoveryClient
@ComponentScan(value = {
"com.chia.multienty.core",
"org.example.saas.core",
"org.example.saas.order",
})
@EnableDubbo
@MapperScan(value={"com.chia.multienty.core.mapper","org.example.saas.core.mapper"})
public class OrderApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(OrderApplication.class, args);
}
}
好了,idea中差不多了,切换到nacos管理后台,配置订单服务模块
Nacos配置
saasdemo-order-dev.yml
在dev中创建saasdemo-order-dev.yml
spring:
shardingSphere:
enabled: true
rabbitmq:
enabled: true
datasource:
type: com.alibaba.druid.pool.DruidDataSource
dynamic:
enabled: true
primary: sharding
datasource:
ds_root:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://xxxx.xxx:3333/mysql?autoReconnect=true&useUnicode=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: root
password: xxxxxxx
kuta:
multi-tenant:
domain: order.xxxx.xxxx
security:
auth:
header: X-TOKEN
# ALL 接受所有平台token
token-prefix: ALL
base64-secret: xxxxxxxx
# 令牌持有时间(秒)
token-holding-time: 86400
# 客户持有令牌时间,-1永久
customer-token-time: 86400
# 续期时长
renew-time: 86400
# 是否支持多点登陆
multipoint-login-enabled: true
ignore-paths:
- /file/upload
- /code/generate
rsa:
private-key: xxxxxxxx
public-key: xxxxxxxxx==
wechat:
pay:
v3NotifyUrls:
order-pay: ${spring.kuta.multi-tenant.domain}/trade/wx/handleWxV3PayNotify/%s
file:
# 大写
storage-mode: LOCAL
custom:
custom-file-upload-service-impl-class: org.example.saas.core.strategy.file.impl.QNYFileUploadServiceImpl
local:
path-prefix: C:\projects\multi-tenant\store
url-prefix: https://${spring.kuta.multi-tenant.domain}/local/
code-generator:
author: "Multienty Auto Generator"
root-package: org.example.saas
common-module-name: saasdemo-core
table-prefix: saas_
controller-module-name: saasdemo-order
# controller save path=project-path(user.dir) + "/" + controller-module-name + controller-file-path-suffix
controller-file-path-suffix: /src/main/java/org/example/saas/order/controller
dto-file-path-suffix: /src/main/java/org/example/saas
# AUTO, NONE, INPUT, ASSIGN_ID, ASSIGN_UUID
id-type: INPUT
logic-delete-column-name: deleted
dto-full-package-name: org.example.saas.core.domain.dto
table-fills:
version: INSERT
create_time: INSERT
update_time: UPDATE
deleted: INSERT
status: INSERT
packages:
controller: order.controller
entity: core.pojo
service: core.service.order
mapper: core.mapper
service-impl: core.service.order.impl
dto: core.domain.dto
parameter: core.parameter
formatter:
controller: "%sController"
entity: "%s"
service: "%sService"
service-impl: "%sServiceImpl"
mapper: "%sMapper"
xml: "%sMapper"
database:
host: xxxxx.xxxx
port: 3333
db-name: saas_order_1
username: saas_order_1
password: xxxxx
package-merge-mapping:
Trade: order
Order: order
OrderDetail: order
OrderItem: order
OrderItemAttr: order
PayLog: order
ShoppingCart: order
tables:
- saas_trade
- saas_order
- saas_order_detail
- saas_order_item
- saas_order_item_attr
shardingsphere-saasdemo-order.yml
在dev中创建shardingsphere-saasdemo-order.yml
spring:
shardingsphere:
enabled: true
dataSource:
common:
type: com.alibaba.druid.pool.DruidDataSource
validationQuery: SELECT 1 FROM DUAL
names:
ds_order_1, ds_order_2
ds_order_1:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://xxxx:xxxx/saas_order_1?autoReconnect=true&useUnicode=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: saas_order_1
password: xxxxxxx
ds_order_2:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://xxxxxx:xxxx/saas_order_2?autoReconnect=true&useUnicode=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: saas_order_2
password: xxxxxx
rules:
sharding:
tables:
saas_trade:
actualDataNodes: ds_order_${1..2}.saas_trade_${com.chia.multienty.core.sharding.tools.ShardingAlgorithmTool.tableNames("saas_trade")}
tableStrategy:
standard:
shardingAlgorithmName: create-time-standard
shardingColumn: create_time
saas_order:
actualDataNodes: ds_order_${1..2}.saas_order_${com.chia.multienty.core.sharding.tools.ShardingAlgorithmTool.tableNames("saas_order")}
tableStrategy:
standard:
shardingAlgorithmName: create-time-standard
shardingColumn: create_time
saas_order_detail:
actualDataNodes: ds_order_${1..2}.saas_order_detail_${com.chia.multienty.core.sharding.tools.ShardingAlgorithmTool.tableNames("saas_order_detail")}
tableStrategy:
standard:
shardingAlgorithmName: create-time-standard
shardingColumn: create_time
saas_order_item:
actualDataNodes: ds_order_${1..2}.saas_order_item_${com.chia.multienty.core.sharding.tools.ShardingAlgorithmTool.tableNames("saas_order_item")}
tableStrategy:
standard:
shardingAlgorithmName: create-time-standard
shardingColumn: create_time
saas_order_item_attr:
actualDataNodes: ds_order_${1..2}.saas_order_item_attr_${com.chia.multienty.core.sharding.tools.ShardingAlgorithmTool.tableNames("saas_order_item_attr")}
tableStrategy:
standard:
shardingAlgorithmName: create-time-standard
shardingColumn: create_time
shardingAlgorithms:
create-time-standard:
type: CLASS_BASED
props:
strategy: standard
algorithmClassName: com.chia.multienty.core.sharding.algorithm.CreateTimeShardingAlgorithm
order-db-inline:
type: INLINE
props:
algorithm-expression: ds_order_${tenant_id % 2 + 1}
defaultDatabaseStrategy:
standard:
shardingColumn: tenant_id
shardingAlgorithmName: order-db-inline
bindingTables:
- saas_order, saas_order_detail, saas_order_item, saas_order_item_attr
props:
sql-show: true
构建订单服务模块环境
生成数据表
OK, 订单模块配置完成,启动OrderApplication
订单服务模块数据表已生成
生成订单模块代码
接下来生成订单模块的代码
代码已生成
我们来看看订单服务模块这种分库分表的代码和用户服务模块只分库生成代码的区别
package org.example.saas.core.service.order.impl;
import org.example.saas.core.pojo.Trade;
import org.example.saas.core.mapper.TradeMapper;
import org.example.saas.core.service.order.TradeService;
import com.chia.multienty.core.mybatis.service.impl.KutaBaseServiceImpl;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.example.saas.core.domain.dto.TradeDTO;
import org.example.saas.core.parameter.order.TradeDetailGetParameter;
import org.example.saas.core.parameter.order.TradePageGetParameter;
import org.example.saas.core.parameter.order.TradeDeleteParameter;
import org.example.saas.core.parameter.order.TradeSaveParameter;
import org.example.saas.core.parameter.order.TradeUpdateParameter;
import org.example.saas.core.parameter.order.TradeEnableParameter;
import org.example.saas.core.parameter.order.TradeDisableParameter;
import com.github.yulichang.toolkit.MPJWrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import com.chia.multienty.core.domain.constants.MultiTenantConstants;
import com.chia.multienty.core.mybatis.MTLambdaWrapper;
import com.chia.multienty.core.util.ListUtil;
import com.chia.multienty.core.domain.enums.StatusEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chia.multienty.core.tools.MultiTenantContext;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.chia.multienty.core.tools.IdWorkerProvider;
/**
* <p>
* 交易 服务实现类
* </p>
*
* @author Multi Tenant Auto Generator
* @since 2024-02-25
*/
@Service
@RequiredArgsConstructor
@DS(MultiTenantConstants.DS_SHARDING)
public class TradeServiceImpl extends KutaBaseServiceImpl<TradeMapper, Trade> implements TradeService {
@Override
public TradeDTO getDetail(TradeDetailGetParameter parameter) {
return selectJoinOne(TradeDTO.class,
MPJWrappers.<Trade>lambdaJoin()
.eq(Trade::getTenantId, parameter.getTenantId())
.eq(Trade::getCreateTime, parameter.getCreateTime())
.eq(Trade::getTradeId, parameter.getTradeId()));
}
@Override
public void update(TradeUpdateParameter parameter) {
Trade trade = new Trade();
BeanUtils.copyProperties(parameter, trade);
update(trade, new LambdaQueryWrapper<Trade>()
.eq(Trade::getTenantId, parameter.getTenantId())
.eq(Trade::getCreateTime, parameter.getCreateTime())
.eq(Trade::getTradeId, parameter.getTradeId()));
}
@Override
public void delete(TradeDeleteParameter parameter) {
removeTE(new LambdaQueryWrapper<Trade>()
.eq(Trade::getTenantId, parameter.getTenantId())
.eq(Trade::getCreateTime, parameter.getCreateTime())
.eq(Trade::getTradeId, parameter.getTradeId()));
}
@Override
public IPage<TradeDTO> getPage(TradePageGetParameter parameter) {
return selectJoinListPage(parameter.getPageObj(), TradeDTO.class,
new MTLambdaWrapper<Trade>()
.solveGenericParameters(parameter)
.eq(Trade::getTenantId, parameter.getTenantId())
.in(!ListUtil.isEmpty(parameter.getTradeIds()),
Trade::getTradeId,
parameter.getTradeIds())
);
}
@Override
public void save(TradeSaveParameter parameter) {
Trade trade = new Trade();
BeanUtils.copyProperties(parameter, trade);
trade.setTradeId(IdWorkerProvider.next());
saveTE(trade);
trade.setTenantId(MultiTenantContext.getTenant().getTenantId());
parameter.setTradeId(trade.getTradeId());
}
@Override
public void enable(TradeEnableParameter parameter) {
Trade trade = new Trade();
BeanUtils.copyProperties(parameter, trade);
trade.setStatus(StatusEnum.NORMAL.getCode());
update(trade, new LambdaQueryWrapper<Trade>()
.eq(Trade::getTenantId, parameter.getTenantId())
.eq(Trade::getCreateTime, parameter.getCreateTime())
.eq(Trade::getTradeId, parameter.getTradeId()));
}
@Override
public void disable(TradeDisableParameter parameter) {
Trade trade = new Trade();
BeanUtils.copyProperties(parameter, trade);
trade.setStatus(StatusEnum.DISABLED.getCode());
update(trade, new LambdaQueryWrapper<Trade>()
.eq(Trade::getTenantId, parameter.getTenantId())
.eq(Trade::getCreateTime, parameter.getCreateTime())
.eq(Trade::getTradeId, parameter.getTradeId()));
}
}
因为我们是用租户编号分库, 按年月组合进行分表,所以在各个接口中均包含了tenantId和createTime字段。
由于篇幅原因,文章到此结束,下一章我们将开始模拟创建订单(因为demo中未演示商品相关模块,所以商品信息我们将模拟填写)
OK,bye!