feat: 简化技术描述语言(2.10~2.11)

This commit is contained in:
dayjoy
2025-08-20 11:02:31 +08:00
parent 1dcb2ce6a0
commit f253b4f628

View File

@@ -964,75 +964,78 @@ meeting_with_room_and_agenda_wo示例
- 如有结果数据二次处理建议在QueryService和QueryExecutor中扩展代码不建议修改QTO文件 - 如有结果数据二次处理建议在QueryService和QueryExecutor中扩展代码不建议修改QTO文件
#### **2.10 查询传输对象(QTO)** #### **2.10 查询传输对象(QTO)**
- **定义与用途:** 在TOCO中QTO读方案的查询参数结构每个读方案对应一个QTO,读方案调用方按照QTO结构向读方案生成的RPC方法传入需要查询的实体字段值,完成数据库查询 - **定义与用途:** QTO读方案的查询参数结构每个读方案对应一个QTO调用方使用QTO结构传入查询字段值,完成数据库查询
- **如何创建/生成:** 创建读方案后TOCO自动生成QTO作为该读方案传入的查询参数结构无需单独创建 - **如何创建/生成:** 创建读方案后TOCO自动生成对应的QTO。无需单独创建
- **关键配置:** 名称(${ReadPlanNameQto},驼峰展示),查询字段列表(如idIsnameLike, schoolNameLike等) - **关键配置:** 名称(${ReadPlanNameQto},驼峰命名),查询字段列表如idIsnameLikeschoolNameLike等
- **与API的关系:** QTO通常可作为API参数API接收参数后直接透传给内部RPC进行调用,注意QTO只用读操作参数,**禁止用写参数结构** - **与API的关系:** QTO可作为API参数API接收参数后直接透传给内部RPC调用。QTO只用读操作参数,**禁止用写参数结构**
#### **2.11 写方案 (WritePlan单聚合操作)** #### **2.11 写方案 (WritePlan单聚合操作)**
- **定义与用途:** TOCO针对写场景定义了一种写方案所有对数据库写操作都只能通过写方案实现(一个写方案只可以变更一个聚合的数据,无法同时操作多个聚合!)。写方案包含了对数据库表的写操作。每个写方案只能操作一个聚合内部的表,同时对一个聚合内表的操作尽量合并至一个写方案中(根据复用性、内聚性等方面具体情况具体分析)。注意写方案可以一次操作聚合内的多张表,如location和storey是同一个聚合并且location和storey是**1:N**关系,location是父对象聚合根storey是子对象那么我们可以创建一个写方案同时更新单个聚合根location中的信息以及操作其下的子表storey**列表**信息,如新增删除修改storey等;也可创建一个写方案单独更新单个子表storey对象信息 - **定义与用途** 写方案是数据库写操作的唯一方式,每个写方案只能变更一个聚合的数据。写方案可以一次操作聚合内的多张表。例如:location(父对象/聚合根)和storey(子对象)是1:N关系可创建写方案同时更新location信息和操作storey列表(新增/删除/修改)也可创建写方案单独更新单个storey对象。
- **关键配置:** 名称(小写字母+下划线,不以write_plan结尾,全局唯一),操作的聚合,聚合内的实体和字段,每个实体的操作类型:CREATE创建**单个**实体UPDATE(更新**单个**实体), DELETE(删除**单个**实体), CREATE_ON_DUPLICATE_UPDATE(创建或者更新**单个**实体),FULL_MERGE( 批量更新**列表**数据根据传入的列表数据一条一条执行CREATE_ON_DUPLICATE_UPDATE的操作并且删除掉老的列表中不在传入列表数据中的部分), PARTIAL_MERGE(批量更新**列表**数据,根据传入的列表数据,一条一条执行) - **关键配置** 名称(小写+下划线不以write_plan结尾全局唯一),操作的聚合,聚合内的实体和字段,每个实体的操作类型:
- **与RPC的关系:** 对于每一个写方案TOCO会自动生成一个RPC方法其参数为写方案对应的BTO返回值为本次操作的聚合根实体的主键值内部只实现了对当前聚合的数据库操作 - CREATE创建单个实体
- **生成的写方案RPC** 的使用: 写方案生成的RPC属于该写方案所属的模块其他模块如果需要调用该写方案需要先订阅该写方案RPC在生成代码后使用adapter调用该读服务当前模块则可以直接调用该写方案对应的Service - UPDATE更新单个实体
- **与聚合的关系:** 每个聚合下可以定义多个写方案,但每个写方案只能操作一个聚合内的表,无法同时操作多个聚合内的表 - DELETE删除单个实体
- **如何创建/生成:** 创建写方案时需要先选定对应的聚合,以及要操作的聚合内部的实体,然后确定对每个实体的具体操作类型 - CREATE_ON_DUPLICATE_UPDATE创建或更新单个实体
- 提取需求中的更新部分需求,根据上下文信息构建出一个写更新方案 - FULL_MERGE批量更新列表数据执行CREATE_ON_DUPLICATE_UPDATE操作删除不在传入列表中的旧数据
- 上下文中输入了备选聚合对象的的定义,每个聚合对象定义了多个实体的嵌套关系 - PARTIAL_MERGE批量更新列表数据执行CREATE_ON_DUPLICATE_UPDATE操作
- 先明确聚合实体的父子关系层级 - **与RPC关系** 每个写方案自动生成一个RPC方法参数为对应BTO返回值为聚合实体主键值,只实现当前聚合的数据库操作。
- 根据需求提取出变更相关的名称 - **生成RPC使用** 写方案RPC属于所属模块其他模块需先订阅该RPC用adapter调用当前模块直接调用对应Service。
- 根需求提取出变更相关的描述 - **与聚合关系:** 每个聚合可定义多个写方案,但每个写方案只能操作一个聚合内的表。
- 根据需求选择确定变更范围,选出一个最合适的聚合对象;注意: 最多只能选择一个聚合对象 - **创建方式:** 先选定聚合和要操作的实体,再确定每个实体的操作类型
- 根据需求在选定的聚合对象按照对象的粒度,选出所需变更对象 - 提取需求中的更新需求,根据上下文构建写方案
- 根据需求选定变更对象的字段;每个选定的对象至少需要选定一个字段,如果无法确定任何字段,默认选择全部字段, 字段必须明确指定名称,不能类似“所有字段”的模糊表达 - 输入备选聚合对象定义,每个聚合定义多个实体的嵌套关系
- 每个对象上可以设置对应的一个操作操作包括CREATE创建UPDATE(更新), DELETE(删除), CREATE_ON_DUPLICATE_UPDATE(创建或者更新),FULL_MERGE( 批量更新列表数据根据传入的列表数据一条一条执行CREATE_ON_DUPLICATE_UPDATE的操作并且删除掉老的列表中不在传入列表数据中的部分), PARTIAL_MERGE(批量更新列表数据根据传入的列表数据一条一条执行CREATE_ON_DUPLICATE_UPDATE的操作) - 明确聚合内实体的父子层级关系
- 列表属性可以批量操作 - 提取需求相关的变更名称和描述
- 批量更新列表数据(FULL_MERGE或者PARTIAL_MERGE),则操作方案需要包含它的父对象 - 选择最合适的聚合对象(最多只能选一个)
- 批量删除列表数据则操作方案需要包含父对象父对象的操作设置为UPDATE - 按对象粒度选出需变更对象
- 批量创建列表数据则操作方案需要包含父对象父对象的操作设置为UPDATE、或者是CREATE当父对象也需要一起创建的时候 - 选定变更对象的字段(每个对象至少选一个字段,无法确定时默认选全部,字段必须明确指定名称)
- 举例meeting对象有List<meeting_agenda> agdendaList属性如果需要批量创建agenda则需要同时设置metting对象和meeting_agenda对象并且对meeting_agenda设置create操作这是会生成一个Bto参数其中包含了 List<meeting_ageda> agendaList的属性用于批量传递参数反正如果只设置了meeting_agenda的create操作生成的Bto参数只包含了meeting_agenda实体的属性表示一次只能创建一条数据 同理对于UPDATE、DELETE也是类似的规则 - 为每个对象设置操作类型
- FULL_MERGE和PARTIAL_MERGE只能用在列表属性上, 单值属性请使用CREATE_ON_DUPLICATE_UPDATE - 列表属性可批量操作:
- 操作是 UPDATE、DELETE、CREATE_ON_DUPLICATE_UPDATE、FULL_MERGEPARTIAL_MERGE的时候必须且只能指定一个唯一键(unique_key)(包括主键),用于确定对应的数据记录主键对应的字段也要包含在fields字段中; - 批量更新列表(FULL_MERGE/PARTIAL_MERGE):需包含父对象
- 唯一键(unique_key)的具体解释:在实体中,存在普通索引和唯一索引,这里的唯一键值的是唯一索引,由一个或多个字段组成 - 批量删除列表需包含父对象父对象设为UPDATE
- 选定的对象层级不能跳跃;如果发生不连续,去掉不连续的叶子对象 - 批量创建列表需包含父对象父对象设为UPDATE或CREATE
- 注意父对象和下一层子对象的操作类型有如下限制,必须严格检查以下规则 - 示例meeting对象有List<meeting_agenda> agendaList批量创建agenda需同时设置meeting和meeting_agenda对象meeting_agenda设为CREATE只设置meeting_agenda的CREATE则一次只能创建一条数据
- 如果父对象的操作是DELETE则下一层子对象不能选择也不能能设定任何操作 - FULL_MERGE和PARTIAL_MERGE只用于列表属性单值属性用CREATE_ON_DUPLICATE_UPDATE
- 如果父对象是的操作是CREATE则下一层子对象只能选择CREATE - UPDATE/DELETE/CREATE_ON_DUPLICATE_UPDATE/FULL_MERGE/PARTIAL_MERGE操作必须指定一个唯一键(包括主键)用于确定数据记录主键字段也要包含在fields中
- 如果父对象是CREATE_ON_DUPLICATE_UPDATE子对象只能是CREATE或者CREATE_ON_DUPLICATE_UPDATE或者FULL_MERGE或者PARTIAL_MERGE - 唯一键:实体中的唯一索引,由一个或多个字段组成
- 如果父对象是FULL_MERGE子对象只能是FULL_MERGE或者PARTIAL_MERGE或者是CREATE - 选定对象层级不能跳跃,发生不连续时去掉不连续的叶子对象
- 对于选定的字段列表中的字段如果字段的类型是Long、BigDecimal、Float 、Integer 则可以设置为增量更新字段, 把值设置在incrFields属性中和操作"UPDATE"、"CREATE_ON_DUPLICATE_UPDATE"、"PARTIAL_MERGE"或者"FULL_MERGE"搭配表示对该字段增量更新: 例如A实体的字段count类型是Long, 如果该字段被设置为增量跟新字段最终的效果是A.count = A.count + ? ; 对于减少字段的值也用该方法表示,可以通过传入负值的入参达到减值的效果 - 父对象和子对象操作类型限制:
- **写方案设计元素的表达**: - 父对象DELETE子对象不能选择任何操作
- 父对象CREATE子对象只能CREATE
以json格式表达json schema 定义如下: - 父对象CREATE_ON_DUPLICATE_UPDATE子对象只能CREATE/CREATE_ON_DUPLICATE_UPDATE/FULL_MERGE/PARTIAL_MERGE
- 父对象FULL_MERGE子对象只能FULL_MERGE/PARTIAL_MERGE/CREATE
- 增量更新字段Long/BigDecimal/Float/Integer类型字段可设为增量更新设置在incrFields中配合UPDATE/CREATE_ON_DUPLICATE_UPDATE/PARTIAL_MERGE/FULL_MERGE使用。例如A实体count字段设为增量更新效果是A.count = A.count + ?,传入负值可减值
- **写方案设计元素表达:**
```json ```json
{ {
"type":"object", "type":"object",
"description":"写方案定义", "description":"写方案定义",
"properties":{ "properties":{
"uuid":{"type":"string","description":"写方案设计元素的唯一标识,在创建的时候不传更新的时候必须传递"}, "uuid":{"type":"string","description":"写方案唯一标识,创建时不传更新时必传"},
"name":{"type":"string","description":"写方案名称,英语表示,单词之间使用下划线连接,长度限制在32字符内"}, "name":{"type":"string","description":"写方案名称,英文+下划线,32字符内"},
"description":{"type":"string","description":"写方案描述,长度限制在256字符内"}, "description":{"type":"string","description":"写方案描述256字符内"},
"bo": {"type":"string","description":"聚合根名称,确定了唯一聚合"}, "bo": {"type":"string","description":"聚合根名称"},
"operations": { "operations": {
"type":"array","description":"定义了对写方案涉及到的相关实体操作,包括操作类型和相关字段", "type":"array","description":"实体操作定义,包括操作类型和字段",
"items":{ "items":{
"type": "object", "description":"定义了对具体一个实体操作,包括操作类型和相关字段", "type": "object", "description":"具体实体操作定义",
"properties":{ "properties":{
"bo":{"type":"string","description":"具体操作的实体"}, "bo":{"type":"string","description":"操作的实体"},
"action":{"type":"string","description":"对具体实体操作"}, "action":{"type":"string","description":"实体操作类型"},
"uniqueKey": { "uniqueKey": {
"type":"array", "type":"array",
"description":"唯一键包含的字段列表,该唯一键用于确定数据记录", "description":"唯一键字段列表,用于确定数据记录",
"items":{"type":"string","description":"字段名称,组成唯一键的字段名称"} "items":{"type":"string","description":"字段名称"}
}, },
"fields":{ "fields":{
"type":"array", "type":"array",
"items":{"type":"string","description":"字段名称必须来自bo对象"}, "items":{"type":"string","description":"字段名称必须来自bo对象"},
"description":"对选定的Bo的操作字段列表" "description":"操作字段列表"
}, },
"incrFields":{ "incrFields":{
"type":"array", "type":"array",
"items":{ "type":"string", "description":"增量字段名称"}, "items":{ "type":"string", "description":"增量字段名称"},
"description":"选定的字段中进行增量操作字段列表" "description":"增量操作字段列表"
}, },
"required":["bo","action","fields"] "required":["bo","action","fields"]
} }
@@ -1042,12 +1045,12 @@ meeting_with_room_and_agenda_wo示例
"required":["name","description","operations","bo"] "required":["name","description","operations","bo"]
} }
``` ```
- **例子** - **示例:**
- **上下文:** - **上下文**
<code> ```java
public class meeting {//会议聚合 public class meeting {//会议聚合
//唯一键:(id)、(meeting_name) //唯一键:(id)、(meeting_name)
Long id; //主键id Long id; //主键
String meeting_name; //会议名称 String meeting_name; //会议名称
Date start_time; //开始时间 Date start_time; //开始时间
Date end_time;//结束时间 Date end_time;//结束时间
@@ -1075,10 +1078,10 @@ meeting_with_room_and_agenda_wo示例
String nickname;//昵称 String nickname;//昵称
Long friend_count;//好友数量 Long friend_count;//好友数量
} }
</code> ```
- **需求:** 创建会议 - **需求** 创建会议
- 对应写方案定义: - **对应写方案定义**
<code> ```json
{ {
"name": "create_meeting", "name": "create_meeting",
"description": "创建会议", "description": "创建会议",
@@ -1095,56 +1098,50 @@ meeting_with_room_and_agenda_wo示例
} }
] ]
} }
</code> ```
- **代码产物和修改建议**
- **BOService:** - **代码产物和修改建议:**
* **生成产物:** 在对应的聚合服务BOService里生成一个函数 - **BOService**
* **函数命名规则:** 和写方案同名 * **生成产物:** 在聚合服务BOService中生成一个函数
* **职责:** 按需对入参进行转换调用BaseBOService里的函数完成对聚合对象的操作, 实现对数据库的写操作; * **函数命名:** 与写方案同名
* **返回值:** 操作的聚合根实体记录的主键字段的值 * **职责:** 转换入参调用BaseBOService函数完成聚合对象操作实现数据库写操作
* **BOService的类路径:** <code>**.service</code> * **返回值:** 聚合根实体记录主键值
* **唯一标识符位置:** 其对应的标识符在函数的注解@AutoGenerated中指定, uuid规则: ${WritePlan在TOCO中的uuid} * **类路径:** `**.service`
- **BaseBOService** * **唯一标识:** 函数注解@AutoGenerated中指定uuid规则${WritePlan的uuid}
- **生成产物:** 在对应的聚合的BaseBOService里生成一系列函数根据入参完成对聚合对象的变更 - **BaseBOService**
- **职责** 增对每个实体的生成增删改的函数,并且根据参数的结构以及聚合的结构,构建嵌套的调用逻辑,完成对一个聚合对象变更,记录并且返回对应的变更情况 - **生成产物:** 在聚合BaseBOService中生成系列函数根据入参完成聚合对象变更
- **类路径:** <code>**.service.base</code> - **职责:** 为每个实体生成增删改函数,根据参数结构和聚合结构构建嵌套调用逻辑,完成聚合对象变更,记录并返回变更情况
- **禁止** 修改该类 - **类路径:** `**.service.base`
- **BTO (业务变更传输对象)** - **禁止:** 修改该类
* **生成产物:** 一个Java类以内部类的方式表示层级结构, **注意** BTO只能由写方案生成不能凭空创建 - **BTO (业务变更传输对象)**
* **命名规则:** 一个Bto结尾(${WritePlanName}Bto驼峰展示) * **生成产物:** Java类以内部类方式表示层级结构注意BTO只能由写方案生成不能凭空创建
* **禁止** 修改该类 * **命名规则:** 以Bto结尾(${WritePlanName}Bto驼峰命名)
* **类路径:** 位于<code>**.service.bto</code>包路径下 * **禁止:** 修改该类
* **职责:** 在**TOCO**中BTO为写方案的参数结构每个写方案会对应一个BTO写方案调用方按照BTO的结构向写方案生成的RPC方法传入需要查询的实体字段值完成对数据库的变更 * **类路径:** `**.service.bto`包下
* **唯一标识符位置:** 其对应的唯一标识符在类注解@AutoGenerated中指定, uuid规则: ${WritePlan在TOCO中的uuid}|BTO|DEFINITION * **职责:** 写方案的参数结构每个写方案对应一个BTO调用方按BTO结构向写方案RPC方法传入实体字段值完成数据库变更
- **例子:** * **唯一标识:** 类注解@AutoGenerated中指定uuid规则${WritePlan的uuid}|BTO|DEFINITION
- 创建用户以及用户设置的写方案create_user_and_setting生成CreateUserAndSettingBto, 在用户的聚合(UserBO)对应的UserBOService中生成函数createUserAndSetting该函数调用BaseUserBOService中生成的createUserAndSetting, 其中在BaseUserBOService中还生成了createUser和createSetting的函数, 一起完成了用户的创建和设置创建的逻辑。 - **示例:**
- 创建用户及设置的写方案create_user_and_setting生成CreateUserAndSettingBto在UserBOService中生成函数createUserAndSetting该函数调用BaseUserBOService中生成的createUserAndSetting其中BaseUserBOService还生成createUser和createSetting函数一起完成用户创建和设置创建逻辑。
- **修改建议:** - **修改建议:**
- 不能修改BaseBOService中的函数不建议修改BTO文件。建议在BOService中进行手动代码扩展,处理可能被复用的修改前后逻辑,如修改数据库前后值对比、常被复用的校验逻辑业务不变性校验逻辑除外、需要经常在一个事务内执行的其他写操作等。 - 不能修改BaseBOService函数不建议修改BTO文件。建议在BOService中扩展代码,处理可能被复用的前后逻辑,如数据库前后值对比、常被复用的校验逻辑(业务不变性校验除外)、需要在一个事务内执行的其他写操作等。
- 父类函数返回一个BoResult类此类记录了各个Bto和Bo实例对应关系,以及各个Bto实例操作结果, 可以通过以下接口获取。 例如:创建用户的写方案中BoService里的入参为CreateUserBto 例如在创建用户的写方案中BoService里的入参为CreateUserBto,用户id由数据库生成如果需要返回创建用户id那么通过boResult.getAddedResult(createUserBto).getBo().getId()可以返回新建用户id - 父类函数返回BoResult类记录各Bto和Bo实例对应关系Bto实例操作结果,可通过以下接口获取。例如创建用户的写方案中BoService入参为CreateUserBto用户id由数据库生成需要返回创建用户id通过boResult.getAddedResult(createUserBto).getBo().getId()返回新建用户id
<code> ```java
/** /**
* 获取更新成功的bto结果 * 获取更新成功的bto结果
*
* @return
*/ */
public UpdatedBto getUpdatedResult(final Object bto) public UpdatedBto getUpdatedResult(final Object bto)
/** /**
* 获取成功插入的Bto结果 * 获取成功插入的Bto结果
* @param btoObj
* @return
*/ */
public AddedBto getAddedResult(final Object btoObj) public AddedBto getAddedResult(final Object btoObj)
/** /**
* 获取Bto对应的删除结果 * 获取Bto对应的删除结果
*
* @param btoObj
* @return
*/ */
public DeletedBto getDeletedResult(final Object btoObj) public DeletedBto getDeletedResult(final Object btoObj)
</code> ```
<code> ```java
public class UpdatedBto<Bto,Entity,BO> { public class UpdatedBto<Bto,Entity,BO> {
//Bto入参 //Bto入参
private Bto bto; private Bto bto;
@@ -1153,9 +1150,9 @@ meeting_with_room_and_agenda_wo示例
//bo后项 //bo后项
private BO bo; private BO bo;
} }
</code> ```
<code> ```java
//记录删除记录情况 //记录删除记录情况
@Setter @Setter
@Getter @Getter
public class DeletedBto<Bto,Entity> { public class DeletedBto<Bto,Entity> {
@@ -1164,8 +1161,8 @@ meeting_with_room_and_agenda_wo示例
//Bto对应的Entity前项 //Bto对应的Entity前项
private Entity entity; private Entity entity;
} }
</code> ```
<code> ```java
//记录Bto创建的前后值 //记录Bto创建的前后值
@Setter @Setter
@Getter @Getter
@@ -1175,7 +1172,7 @@ meeting_with_room_and_agenda_wo示例
//bo后项 //bo后项
private BO bo; private BO bo;
} }
</code> ```
#### **2.12 业务变更传输对象(BTO)** #### **2.12 业务变更传输对象(BTO)**
- **定义与用途:** 在TOCO中BTO为写方案自动生成的参数结构每个写方案会生成一个BTO。BTO为写方案选定的操作实体根据关系形成的树形集合最外层为聚合根。写方案调用方按照BTO的结构向写方案生成的RPC方法传入需要操作的实体字段值完成对数据库的写操作 - **定义与用途:** 在TOCO中BTO为写方案自动生成的参数结构每个写方案会生成一个BTO。BTO为写方案选定的操作实体根据关系形成的树形集合最外层为聚合根。写方案调用方按照BTO的结构向写方案生成的RPC方法传入需要操作的实体字段值完成对数据库的写操作
@@ -1196,6 +1193,7 @@ meeting_with_room_and_agenda_wo示例
a. 如果接口有一个主要的写场景则创建一个主要的写方案让其自动生成的BTO作为API参数然后再增加其他基本类型的参数或EO a. 如果接口有一个主要的写场景则创建一个主要的写方案让其自动生成的BTO作为API参数然后再增加其他基本类型的参数或EO
b. 使用基本类型参数或EO作为参数在接口执行流程中将基本类型参数转换为各个写方案自动生成的BTO再调用多个写方案 b. 使用基本类型参数或EO作为参数在接口执行流程中将基本类型参数转换为各个写方案自动生成的BTO再调用多个写方案
c. 如果流程过于复杂优先考虑使用基本类型参数或EO c. 如果流程过于复杂优先考虑使用基本类型参数或EO
#### **2.13 服务层方法 (RPC)** #### **2.13 服务层方法 (RPC)**
- **定义与用途:** 在TOCO中RPC为服务层的方法。RPC按照可见性可以分为两种一种是公开RPC可以被其他模块订阅订阅后可以通过RPC适配器进行调用另一种是非公开RPC只能被当前模块调用。非公开RPC可以被公开从而被其他模块订阅并调用 - **定义与用途:** 在TOCO中RPC为服务层的方法。RPC按照可见性可以分为两种一种是公开RPC可以被其他模块订阅订阅后可以通过RPC适配器进行调用另一种是非公开RPC只能被当前模块调用。非公开RPC可以被公开从而被其他模块订阅并调用
- **如何创建/生成:** RPC有4种创建方式a.DTO创建后会自动创建RPCRPC的公开性与DTO的公开性保持一致b.返回DTO的读方案会根据分页情况、以及是否生成计数函数的配置自动生成非公开的RPC c.写方案创建后会自动生成非公开的RPC返回值为操作的聚合根实体记录的主键字段的值 d.如果上述三种RPC无法满足需求则可以通过TOCO创建自定义RPC完整指定功能需指定具体的参数和返回值以及公开性等。 - **如何创建/生成:** RPC有4种创建方式a.DTO创建后会自动创建RPCRPC的公开性与DTO的公开性保持一致b.返回DTO的读方案会根据分页情况、以及是否生成计数函数的配置自动生成非公开的RPC c.写方案创建后会自动生成非公开的RPC返回值为操作的聚合根实体记录的主键字段的值 d.如果上述三种RPC无法满足需求则可以通过TOCO创建自定义RPC完整指定功能需指定具体的参数和返回值以及公开性等。
@@ -1228,6 +1226,7 @@ meeting_with_room_and_agenda_wo示例
requestParams为请求参数列表response为返回结构requestParams中每个参数和response的结构相同其中name为参数名;type为参数类型参数类型取值范围为Boolean,String,Integer,Long,Float,Double,BigDecimal,Date,ByteArray,Enum,Eo,Dto,Qto,Bto,List,PageResult,Void其中参数不能为Void和PageResult如果不需要返回值则type设置为Void如果返回值为分页查询的结果则type设置为PageResult且innerType必为Dto对应代码中的VSQueryResult<XxxDto>description为描述typeUuid为参数对应类结构的UUID当type为Enum、Eo、Dto时传入该对象的uuid当type为Qto时传入对应读方案的uuid、当type为Bto时传入对应写方案的uuidinnerType为List内部类型当type为List或PageResult时包含该字段innerUuid为List内部类结构的UUID当type为List或PageResult且innerType为Enum、Eo、Dto时传入该对象的uuid当innerType为Qto时传入对应读方案的uuid、当innerType为Bto时传入对应写方案的uuid。 requestParams为请求参数列表response为返回结构requestParams中每个参数和response的结构相同其中name为参数名;type为参数类型参数类型取值范围为Boolean,String,Integer,Long,Float,Double,BigDecimal,Date,ByteArray,Enum,Eo,Dto,Qto,Bto,List,PageResult,Void其中参数不能为Void和PageResult如果不需要返回值则type设置为Void如果返回值为分页查询的结果则type设置为PageResult且innerType必为Dto对应代码中的VSQueryResult<XxxDto>description为描述typeUuid为参数对应类结构的UUID当type为Enum、Eo、Dto时传入该对象的uuid当type为Qto时传入对应读方案的uuid、当type为Bto时传入对应写方案的uuidinnerType为List内部类型当type为List或PageResult时包含该字段innerUuid为List内部类结构的UUID当type为List或PageResult且innerType为Enum、Eo、Dto时传入该对象的uuid当innerType为Qto时传入对应读方案的uuid、当innerType为Bto时传入对应写方案的uuid。
- **生成代码:** RPC会在service层中生成类文件及实现函数包含DTO自动生成的RPC如UserDtoService.getById(主键为id)或StaffBaseDtoService.getByStaffId(主键为staff_id)、读写方案自动生成的RPC如UserDtoQueryService.queryByListQto、UserBOService.createUser、自定义RPC如UserCustomService.customMethod。特别注意公开的RPC才可被其他模块使用RPC被订阅后会生成RpcAdapter适配器其他模块通过RpcAdapter才可调用该方法。如Order模块订阅了User模块的UserDtoService.getById则会在Order模块中生成UserDtoServiceInOrderRpcAdapter.getById方法Order模块中的代码必须通过@Resource private UserDtoServiceInOrderRpcAdapter userDtoServiceInOrderRpcAdapter;注入适配器后才可进行方法调用。这里**必须要注意**:变量的命名必须是类名的首字母小写,禁止使用其他变量名。 - **生成代码:** RPC会在service层中生成类文件及实现函数包含DTO自动生成的RPC如UserDtoService.getById(主键为id)或StaffBaseDtoService.getByStaffId(主键为staff_id)、读写方案自动生成的RPC如UserDtoQueryService.queryByListQto、UserBOService.createUser、自定义RPC如UserCustomService.customMethod。特别注意公开的RPC才可被其他模块使用RPC被订阅后会生成RpcAdapter适配器其他模块通过RpcAdapter才可调用该方法。如Order模块订阅了User模块的UserDtoService.getById则会在Order模块中生成UserDtoServiceInOrderRpcAdapter.getById方法Order模块中的代码必须通过@Resource private UserDtoServiceInOrderRpcAdapter userDtoServiceInOrderRpcAdapter;注入适配器后才可进行方法调用。这里**必须要注意**:变量的命名必须是类名的首字母小写,禁止使用其他变量名。
- **修改建议:** 建议修改RPC方法不建议修改RPC方法签名、适配器中的内容 - **修改建议:** 建议修改RPC方法不建议修改RPC方法签名、适配器中的内容
#### **2.14 应用程序接口 (API)** #### **2.14 应用程序接口 (API)**
- **定义与用途:** 在TOCO中API用于定义对外暴露的HTTP接口 - **定义与用途:** 在TOCO中API用于定义对外暴露的HTTP接口
- **如何创建/生成:** API一般为通过TOCO创建需指定具体的参数和返回值等。 - **如何创建/生成:** API一般为通过TOCO创建需指定具体的参数和返回值等。
@@ -1266,6 +1265,7 @@ meeting_with_room_and_agenda_wo示例
- **代码产物和修改建议** - **代码产物和修改建议**
- **生成代码:** API会在entrance层生成Controller以及对应的API方法 - **生成代码:** API会在entrance层生成Controller以及对应的API方法
- **修改建议:** 建议修改API方法的实现内容禁止直接修改API方法签名、URI**注意**如需修改API定义名称、出入参数、URL需要通过修改API设计元素实现 - **修改建议:** 建议修改API方法的实现内容禁止直接修改API方法签名、URI**注意**如需修改API定义名称、出入参数、URL需要通过修改API设计元素实现
#### **2.15 流程服务FunctionFlow)** #### **2.15 流程服务FunctionFlow)**
- **定义与用途:** TOCO针对复杂业务拆解定义了流程服务把一个复杂的业务过程根据业务逻辑的内聚性合并逻辑功能把流程分解成流程节点最终构造出一个类似工作流的逻辑流程最终实现复杂业务流程分解提升代码的可维护性。TOCO内嵌了流程引擎在Function_Flow生成代码后可以在流程引擎中执行 - **定义与用途:** TOCO针对复杂业务拆解定义了流程服务把一个复杂的业务过程根据业务逻辑的内聚性合并逻辑功能把流程分解成流程节点最终构造出一个类似工作流的逻辑流程最终实现复杂业务流程分解提升代码的可维护性。TOCO内嵌了流程引擎在Function_Flow生成代码后可以在流程引擎中执行
- **何时使用:** - **何时使用:**
@@ -1396,8 +1396,7 @@ meeting_with_room_and_agenda_wo示例
- 用户登录在UserFlowService中生成一个函数invokeLoginFlow该函数通过流程框架根据流程定义调用LoginNodeLoginNode中封装了用户登录的逻辑LoginFlowContext中封装了用户登录的参数和结果。 - 用户登录在UserFlowService中生成一个函数invokeLoginFlow该函数通过流程框架根据流程定义调用LoginNodeLoginNode中封装了用户登录的逻辑LoginFlowContext中封装了用户登录的参数和结果。
- **修改建议:** 不修改 service 中的函数, 不修改FlowConfig, 可以修改FlowContext, 添加/修改出入参数, 修改FlowNode中的具体业务逻辑。 - **修改建议:** 不修改 service 中的函数, 不修改FlowConfig, 可以修改FlowContext, 添加/修改出入参数, 修改FlowNode中的具体业务逻辑。
#### **2.16 自定义查询**
#### **2.12 自定义查询**
- 在读方案无法满足需求的情况下,可以使用自定义查询 - 在读方案无法满足需求的情况下,可以使用自定义查询
- 自定查询使用复杂的sql实现业务功能 - 自定查询使用复杂的sql实现业务功能
- 自定义查询的数据访问层使用MyBatis、MyBatisPlus实现 - 自定义查询的数据访问层使用MyBatis、MyBatisPlus实现