feat: 简化技术描述语言(3~4)
This commit is contained in:
121
knowledge.md
121
knowledge.md
@@ -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 # 项目级别公共的基础模块
|
||||
### **3 代码生成说明**
|
||||
|
||||
**3.1 技术栈**
|
||||
Java、SpringBoot、MyBatis-plus(读取)、Hibernate(写入)
|
||||
|
||||
**3.2 项目结构**
|
||||
多模块SpringBoot项目,子模块在`/modules`目录下。子模块路径必须从`modules`开始,如:`modules/module1/src/main/java...`
|
||||
|
||||
```
|
||||
项目根目录
|
||||
├── main_module
|
||||
│ ├── common/ # 项目级公共模块
|
||||
│ │ ├── config/ # 中间件配置
|
||||
│ │ ├──constants/ # 项目级别常量
|
||||
│ │ ├──enums/ # 项目级别枚举
|
||||
│ │ ├── constants/ # 项目常量
|
||||
│ │ ├── enums/ # 项目枚举
|
||||
│ │ ├── redis/ # Redis配置
|
||||
│ │ ├── response/ # 返回结果封装
|
||||
│ │ └──utils/ # 项目级别utils
|
||||
└── └── entrance/ # 项目入口
|
||||
│ └──AppApplication.java # 项目启动类
|
||||
└── modules # 子模块列表
|
||||
│ │ └── 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/
|
||||
│ ├── 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/ # 数据传输对象定义
|
||||
│ ├── 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 标准查找流程**
|
||||
│ │ └── 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)设计时,通常会先判断接口的主要功能是读数据库或写数据库,并分析相关的读写方案以及对应的QTO和BTO。如果是读场景,则参数会**优先使**用相关的QTO;如果是写场景,则参数会**优先**使用相关的BTO,如果BTO和QTO无法满足要求,则可以再增加基本类型或Enum、EO等类型参数。参数类型选择时必须遵循以下要求:a.DTO、VO不能作为参数类型;b.QTO、BTO不能作为返回值类型。
|
||||
#### 4.1 接口参数类型和返回值选择:
|
||||
设计TOCO接口(API、RPC)时,先判断主要功能是读库还是写库,分析对应的读写方案及QTO、BTO。读场景**优先**使用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 blance > amount 的 where 条件保护;在toco中,
|
||||
应该1、在写方案中使用incr字段。 2、 在boService中,添加类似保护代码 if(userBo.getBalance >= 0) 进行保护;或则通过userBo的业务不变性(聚合校验),添加balance>=0的校验
|
||||
- 本节描述参数选择的**优先级原则**,非绝对限制
|
||||
- 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知识库>
|
||||
|
||||
Reference in New Issue
Block a user