feat: 简化技术描述语言(3~4)

This commit is contained in:
dayjoy
2025-08-20 11:20:58 +08:00
parent 47199b895c
commit 8d028d116c

View File

@@ -1404,73 +1404,84 @@ class CreateUserBto { //对应实体user
- 自定义查询时框架不自动生成代码(需要手动编写全部代码)
- 各层代码位置严格遵守**3.2 项目结构与导航**必须有mapper层、service层、DO对象、DTO对象API返回数据必须有VO对象
### **3 生成代码产物补充说明**
- **3.1 支持的语言/框架**
Java、SpringBoot、MyBatis-plus(读)、Hibernate(写)
- **3.2 项目结构与导航**
TOCO生成的项目是一个多模块的SpringBoot项目,包括主模块和子模块,它的子模块位于根目录下的/modules目录中**注意** 获取子模块代码文件路径的时候需要从根目录开始所以必须从modules节点开始例如子模块module1下的的java类路径应该是`modules/module1/src/main/java...`
<dir>
|──main_module
│ ├── common # 项目级别公共的基础模块
│ │ ├──config/ # 中间件配置
│ │ ├──constants/ # 项目级别常量
│ │ ├──enums/ # 项目级别枚举
├──redis/ # Redis配置
│ │ ├──response/ # 返回结果封装
│ │ ──utils/ # 项目级别utils
└── └── entrance/ # 项目入口
└──AppApplication.java # 项目启动类
── modules # 子模块列表
└── module1/ # 子模块1
├── common/
│ ├──constants/ # 模块常量
│ ├──utils/ #模块级别utils
│ └──enums/ # 枚举
├── entrance/web/src/main/java/com/{project_name}/{module_name}/entrance/web/
├──controller/ # api 定义
│ ├──converter/ # 把DTO转化成VO
│ ├──vo/ # VO结构定义
│ └── query/ # 把读方案返回的数据转成成VO
│ ├── assembler/ # VO的数据填充
│ ├── collector/ # 读方案返回的id数据展开成完成对象数据
│ └── executor/ # 调用Service的度方案实现同时调用collector和assembler返回最终的VO
├── manager/src/main/java/com/{project_name}/{module_name}/manager/
├── bo/ # 聚合对象定义
── base/ # 聚合对象的基类
│ ├── dto/ # 数据传输对象定义
│ ├── converter/ # 复杂Dto非BaseDto)组装
├── facade/ # 调用其他模块的RPC适配器包含RpcAdapter如UserDtoServiceInMeetingRpcAdapter表示从meeting模块调用user模块中方法
│ └── impl/ # Dto的查询接口的实现
├── persist/src/main/java/com/{project_name}/{module_name}/persist/
│ ├── eo/ # 值对象(Eo)的结构定义
│ ├── dos/ # 数据库单表结构的映射
│ ├── qto/ # 读方案的数据库查询实现
│ └── mapper/ # MyBatis的Mapper定义
└── service/src/main/java/com/{project_name}/{module_name}/service/ # BOService包含某个聚合下所有写方案生成的方法、 DtoService包含DTO生成的预定义方法
├── bto/ # 写方案入参的定义
├── converter/ # 对返回的BaseDto按需进行二次扩展
├── query/ # 查询方案的service层入口调用persist层的查询实现
└── base/ # 每个BOService对应的基类
在一个子模块的内它的依赖层级为entrance -> service -> manager -> persist, 同时各个层都依赖 common
</dir>
- **3.3 标准查找流程**
### **3 代码生成说明**
**3.1 技术栈**
Java、SpringBoot、MyBatis-plus(读取)、Hibernate(写入)
**3.2 项目结构**
多模块SpringBoot项目子模块在`/modules`目录下。子模块路径必须从`modules`开始,如:`modules/module1/src/main/java...`
```
项目根目录
├── main_module
├── common/ # 项目级公共模块
│ │ ├── config/ # 中间件配置
│ │ ── constants/ # 项目常量
│ ├── enums/ # 项目枚举
│ │ ├── redis/ # Redis配置
── response/ # 返回结果封装
└── utils/ # 项目工具类
└── entrance/ # 项目入口
│ └── AppApplication.java # 启动类
└── modules/ # 子模块列表
└── module1/ # 子模块1
├── common/
├── constants/ # 模块常量
│ ├── utils/ # 模块工具类
│ └── enums/ # 模块枚举
├── entrance/web/src/main/java/com/{项目名}/{模块名}/entrance/web/
│ ├── controller/ # API定义
│ ├── converter/ # DTO转VO
├── vo/ # VO结构
└── query/ # 读方案转VO
├── assembler/ # VO数据填充
── collector/ # ID数据展开为完整对象
│ └── executor/ # 调用Service实现返回VO
├── manager/src/main/java/com/{项目名}/{模块名}/manager/
│ ├── bo/ # 聚合对象定义
│ └── base/ # 聚合对象基类
├── dto/ # DTO定义
│ ├── converter/ # 复杂DTO组装
│ ├── facade/ # 跨模块RPC适配器
│ └── impl/ # DTO查询实现
├── persist/src/main/java/com/{项目名}/{模块名}/persist/
│ ├── eo/ # 值对象定义
├── dos/ # 数据库表映射
├── qto/ # 读方案数据库查询
│ └── mapper/ # MyBatis Mapper
└── service/src/main/java/com/{项目名}/{模块名}/service/
├── bto/ # 写方案入参定义
├── converter/ # BaseDto扩展
├── query/ # 查询方案Service入口
└── base/ # BOService基类
模块依赖层级entrance -> service -> manager -> persist各层都依赖common
```
**3.3 查找路径**
1. **API查找** → `modules/{模块名}/entrance/web/controller/`
2. **DTO查找** → `modules/{模块名}/manager/dto/`
3. **Service查找** → `modules/{模块名}/service/`
4. **数据层查找** → `modules/{模块名}/persist/
- **3.4 特殊注解及含义**
TOC自动生成的类和方法会带有@AutoGenerated注解注解中有2个属性:locked为boolean类型如果locked=true则代表该文件或方法不建议修改;uuid为String类型表示该类或方法的唯一标识如果uuid中包含|字符则说明该uuid为特殊格式由不同类型的数据拼装而成(见**[3.2 设计元素到代码的映射规则及修改建议]**中每种设计元素的代码说明)。
- **3.5 代码严格分层**
Service层方法不能返回VO不能调用任何Controller层的方法如VoQueryExecutor、VoConverter等
4. **数据层查找** → `modules/{模块名}/persist/`
**3.4 特殊注解**
自动生成的类和方法有`@AutoGenerated`注解:
- `locked`属性true表示不建议修改
- `uuid`属性:唯一标识,包含`|`字符表示特殊格式拼装
**3.5 分层规则**
Service层方法不能返回VO不能调用Controller层方法(如VoQueryExecutor、VoConverter等)
### 4. TOCO 最佳实践
#### 4.1 接口参数类型和返回值选择(Interface Parameter & Return Type Definition):
在做TOCO接口(API、RPC)设计时,通常会先判断接口的主要功能是读数据库或写数据库,分析相关的读写方案以及对应的QTOBTO。如果是读场景,则参数会**优先使**用相关的QTO如果是写场景则参数会**优先**使用相关的BTO如果BTO和QTO无法满足要求则可以再增加基本类型Enum、EO等类型参数。参数类型选择时必须遵循以下要求a.DTO、VO不能作参数类型b.QTO、BTO不能作返回值类型
**重要说明:**
-节描述的是参数选择的**优先级原则**不是绝对限制
- API参数绝对限制请参考2.14章节
- "优先使用QTO/BTO"意思是在满足规范前提下,根据场景选择最合适的参数类型
#### 4.2 在处理先读后更新的场景的时候为了避免并发引起的数据脏写应该充分利用BoService的校验功能。 例如在账户扣钱的情况为了避免账户在并发扣除余额不足在用raw sql实现中我们一般会 通过 update account set balance = balance - amount where user_id = xxx and blance > amount 的 where 条件保护在toco中
应该1、在写方案中使用incr字段。 2、 在boService中添加类似保护代码 if(userBo.getBalance >= 0) 进行保护或则通过userBo的业务不变性聚合校验添加balance>=0的校验
#### 4.1 接口参数类型和返回值选择:
设计TOCO接口(API、RPC)时,先判断主要功能是读库还是写库,分析对应的读写方案QTOBTO。读场景**优先**使用QTO作参数写场景**优先**使用BTO作参数。QTO、BTO不满足时增加基本类型Enum、EO参数。必须遵循a.DTO、VO不能作参数b.QTO、BTO不能作返回值。
**重要说明:**
- 本节描述参数选择的**优先级原则**绝对限制
- API参数绝对限制2.14章节
- "优先使用QTO/BTO"在满足规范前提下,根据场景选择最合适的参数类型
#### 4.2 并发数据保护最佳实践:
处理先读后更新场景时为避免并发导致数据脏写应充分利用BoService校验功能。例如账户扣钱场景避免并发扣除导致余额不足传统raw sql用 `update account set balance = balance - amount where user_id = xxx and balance > amount` 的where条件保护在TOCO中应该1、写方案中使用incr字段。2、在boService中添加保护代码 `if(userBo.getBalance() >= 0)` 或通过userBo业务不变性聚合校验添加 `balance>=0` 校验。
-----------------------------------------------------------------------------
</TOCO知识库>