更新 llms-full.txt
This commit is contained in:
155
llms-full.txt
155
llms-full.txt
@@ -125,7 +125,62 @@ DateTime endTime; //会议结束时间
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
这种“正向替换”和“反向注入”可以按需递归调用,去将多个互相之间有外键关系的对象组装成最终对象。例如,还有另外一张表MeetingAgenda到Meeting有n:1的外键,和另外一张表AgendaAttendance到MeetingAgenda有n:1外键。那么如果我要去组装以Meeting开始,包含MeetingRoom, MeetingAgenda, AgendaAttendance的组装对象,首先发现MeetingRoom是可以正向扩展到Meeting的,反向注入MeetingAgenda,而AgendaAttendance需要先反向注入到MeetingAgenda中。
|
这种“正向替换”和“反向注入”可以按需递归调用,去将多个互相之间有外键关系的对象组装成最终对象。例如,还有另外一张表MeetingAgenda到Meeting有n:1的外键,和另外一张表AgendaAttendance到MeetingAgenda有n:1外键。那么如果我要去组装以Meeting开始,包含MeetingRoom, MeetingAgenda, AgendaAttendance的组装对象,首先发现MeetingRoom是可以正向扩展到Meeting的,反向注入MeetingAgenda,而AgendaAttendance需要先反向注入到MeetingAgenda中。
|
||||||
- **TOCO中json结构描述:** 在TOCO中,DTO使用一个json结构表示,有时用户会在上下文中提供关于DTO的json描述,所以你需要了解结构中一些关键字段,便于你能够理解用户提供的DTO:expandList为正向替换,reverseExpandList为反向注入,customFieldList为自定义字段。expandListList中,field为正向替换对应的本表外键字段的名字,fieldName为正向替换之后给该字段的起的新名字;reverseExpandList中,field为反向注入对应的他表外键字段的名字,fieldName为反向注入之后给该字段的起的新名字;customFieldList中,uuid为参数对应类结构的UUID,当type为Enum、Eo时包含该字段;innerType为List内部类型,当type为List时包含该字段;innerUuid为List内部类结构的UUID,当type为List且innerType=Enum、Eo时包含该字段。
|
- **TOCO中json结构描述:** 在TOCO中,DTO使用一个json结构表示,该结构可用于理解DTO的含义,或作为创建、更新DTO工具的参数。部分字段的含义为:dto的uuid为唯一标识,如果需要创建DTO,则设置为null;如果需要复用,则填入其uuid。expandList为正向替换,reverseExpandList为反向注入,customFieldList为自定义字段。expandListList中,field为正向替换对应的本表外键字段的名字,fieldName为正向替换之后给该字段的起的新名字;reverseExpandList中,field为反向注入对应的他表外键字段的名字,fieldName为反向注入之后给该字段的起的新名字;customFieldList中,uuid为参数对应类结构的UUID,当type为Enum、Eo时包含该字段;innerType为List内部类型,当type为List时包含该字段;innerUuid为List内部类结构的UUID,当type为List且innerType=Enum、Eo时包含该字段。示例如下:
|
||||||
|
- meeting_with_room_dto
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"dto": {
|
||||||
|
"uuid": null,
|
||||||
|
"name": "meeting_with_room_dto",
|
||||||
|
"description": "会议详情,包含会议室信息,以及其中的会议列表",
|
||||||
|
"fromEntity": "meeting",
|
||||||
|
"expandList": [
|
||||||
|
{
|
||||||
|
"field": "room_id",
|
||||||
|
"fieldName": "meeting_room",
|
||||||
|
"dto": {
|
||||||
|
"uuid": null,
|
||||||
|
"name": "meeting_room_with_meetings_dto",
|
||||||
|
"fromEntity": "meeting_room",
|
||||||
|
"description": "会议室信息,包含会议列表",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"customFieldList":[
|
||||||
|
{
|
||||||
|
"name": "started",
|
||||||
|
"type": "Boolean",
|
||||||
|
"description": "是否开始"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- meeting_room_with_meetings_dto
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"dto": {
|
||||||
|
"uuid": null,
|
||||||
|
"name": "meeting_room_with_meetings_dto",
|
||||||
|
"description": "会议室详情,包含会议室信息,以及其中的会议信息",
|
||||||
|
"fromEntity": "meeting",
|
||||||
|
"reverseExpandList": [
|
||||||
|
{
|
||||||
|
"field": "room_id",
|
||||||
|
"dto": {
|
||||||
|
"uuid": "ffeec02d-2a32-1531-1ce1-b9bfc1993765",
|
||||||
|
"name": "meeting_base_dto",
|
||||||
|
"description": "会议基本信息",
|
||||||
|
"fromEntity": "meeting"
|
||||||
|
},
|
||||||
|
"fieldName": "meeting_list"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
示例中meeting_with_room_dto和meeting_room_with_meetings_dto没有uuid,为待创建的DTO。meeting_base_dto为已存在的DTO,带有uuid。
|
||||||
|
|
||||||
- **预定义方法:** 对于每一个DTO,TOCO会自动其根Entity的唯一索引生成一些预定义的RPC方法及实现,预定义方法不仅获取了根Entity的数据,还通过RPC调用的方式**自动**获取了**所有扩展字段**的数据,并对数据进行了拼装处理。如实体user有unique index(username),则会针对UserDto生成UserDto UserDtoService.getByUserName(String userName)和List<UserDto> UserDtoService.getByUserNames(List<String> userNames)。预定义方法内部根据外键关系自动生成了复杂DTO数据的递归、Join拼装的能力,会直接返回DTO内部的所有继承字段和扩展字段的数据。注意自定义字段的数据获取不会自动生成,需要在对应的convert方法中编写代码。
|
- **预定义方法:** 对于每一个DTO,TOCO会自动其根Entity的唯一索引生成一些预定义的RPC方法及实现,预定义方法不仅获取了根Entity的数据,还通过RPC调用的方式**自动**获取了**所有扩展字段**的数据,并对数据进行了拼装处理。如实体user有unique index(username),则会针对UserDto生成UserDto UserDtoService.getByUserName(String userName)和List<UserDto> UserDtoService.getByUserNames(List<String> userNames)。预定义方法内部根据外键关系自动生成了复杂DTO数据的递归、Join拼装的能力,会直接返回DTO内部的所有继承字段和扩展字段的数据。注意自定义字段的数据获取不会自动生成,需要在对应的convert方法中编写代码。
|
||||||
- **公开性:** DTO可以设置公开性,如果DTO为公开,则其生成的预定义RPC方法也为公开RPC,可以被其他模块订阅并调用;如果DTO为非公开,则其生成的预定义RPC方法也为非公开RPC,其他模块不可见
|
- **公开性:** DTO可以设置公开性,如果DTO为公开,则其生成的预定义RPC方法也为公开RPC,可以被其他模块订阅并调用;如果DTO为非公开,则其生成的预定义RPC方法也为非公开RPC,其他模块不可见
|
||||||
- **跨模块依赖:** 如果DTO内引用了其他模块的DTO,则TOCO会自动订阅其他模块的RPC(getByIds,getBy${foreignKey}等)方法,用来获取对应的DTO
|
- **跨模块依赖:** 如果DTO内引用了其他模块的DTO,则TOCO会自动订阅其他模块的RPC(getByIds,getBy${foreignKey}等)方法,用来获取对应的DTO
|
||||||
@@ -140,10 +195,10 @@ DateTime endTime; //会议结束时间
|
|||||||
注意判断使用哪种方式时,只能根据查询条件判断是否使用读方案,绝对禁止使用返回值是否需要数据拼装来判断!**如果现实中的代码和TOCO中的步骤有冲突时,只能使用TOCO的定义!**
|
注意判断使用哪种方式时,只能根据查询条件判断是否使用读方案,绝对禁止使用返回值是否需要数据拼装来判断!**如果现实中的代码和TOCO中的步骤有冲突时,只能使用TOCO的定义!**
|
||||||
#### **2.7 视图对象 (VO)**
|
#### **2.7 视图对象 (VO)**
|
||||||
- **定义与用途:** 在TOCO中,VO表达某个BaseDTO(如果用户指明派生源,也可使用其他DTO)为派生源,通过外键关系不断关联多个BaseDTO的数据结构。VO用于在视图层与前端之间进行数据传输,往往被当做HTTP API的返回值、或读方案的返回值使用,由服务端返回至前端。注意VO不能作为RPC的返回值。
|
- **定义与用途:** 在TOCO中,VO表达某个BaseDTO(如果用户指明派生源,也可使用其他DTO)为派生源,通过外键关系不断关联多个BaseDTO的数据结构。VO用于在视图层与前端之间进行数据传输,往往被当做HTTP API的返回值、或读方案的返回值使用,由服务端返回至前端。注意VO不能作为RPC的返回值。
|
||||||
- **关键配置:** 名称(以Vo结尾)、根Entity、派生源、字段列表。VO中的字段分为三种:a.继承DTO的字段,和DTO的字段类型一样;b.扩展字段,含正向替换和反向注入字段,类型为VO或List<VO>;c.自定义字段,类型为基本类型或VO类型。VO中的字段来源于DTO,可以根据页面需要进行裁剪,可以根据外键关系扩展其他BaseDto(详见**字段扩展方式**)。如果在派生源中没有合适字段,且明确无法通过外键扩展外部BaseDto的情况下,可增加对应的自定义字段
|
- **关键配置:** 名称(以Vo结尾)、根Entity、派生源、字段列表。VO中的字段分为三种:a.继承DTO的字段,和DTO的字段类型一样;b.扩展字段,含正向替换和反向注入字段,类型为VO或List<VO>;c.自定义字段,类型为基本类型或VO类型。VO中的字段来源于DTO,可以根据页面需要将无用字段进行裁剪,可以根据外键关系扩展其他BaseDto(详见**字段扩展方式**)。如果在派生源中没有合适字段,且明确无法通过外键扩展外部BaseDto的情况下,可增加对应的自定义字段
|
||||||
- **与DTO的区别 (在TOCO语境下): **DTO用于服务层传输,通常作为RPC的返回值,与数据模型更近,复用性较强;VO用于视图层传输,通常作为API的返回值,与UI展示更为接近,复用性较弱。
|
- **与DTO的区别 (在TOCO语境下): **DTO用于服务层传输,通常作为RPC的返回值,与数据模型更近,复用性较强;VO用于视图层传输,通常作为API的返回值,与UI展示更为接近,复用性较弱。
|
||||||
- **如何创建/生成:** VO通常由某个BaseDTO以及外键关系为基础派生,也可以直接创建和DTO无关、内部全为自定义字段的VO(尽量少用,只为应对某些特殊页面,需要组装一组完全无关的返回数据的场景)。
|
- **如何创建/生成:** VO通常由某个BaseDTO以及外键关系为基础派生,也可以直接创建和DTO无关、内部全为自定义字段的VO(尽量少用,只为应对某些特殊页面,需要组装一组完全无关的返回数据的场景)。
|
||||||
- **根VO和子VO:**TOCO中的VO分为两种:1.根VO,指最外层的VO结构,需要经由TOCO创建;2.子VO,某个根VO的内部嵌套VO,通过外键关系关联BaseDTO之后由TOCO自动创建。所以在TOCO中,我们只需要描述VO要描述的字段、扩展关系,并通过**创建根VO**的行为使TOCO**自动创建**其子VO,即可完成一个复杂嵌套VO的创建过程,无需单独创建子VO。
|
- **根VO和子VO:**TOCO中的VO分为两种:1.根VO,指最外层的VO结构,需要经由TOCO创建,有uuid作为唯一标识,根VO可被其他根VO或子VO引用;2.子VO,某个根VO的内部嵌套VO,通过外键关系关联BaseDTO之后由TOCO自动创建,只附属于某个根VO,只能被这一个根VO引用,且没有uuid。所以在TOCO中,我们需要描述VO要的字段、扩展关系,并通过**创建根VO**的行为使TOCO**自动创建**其子VO,或引用其他根VO,即可完成一个复杂嵌套VO的创建过程,无需单独创建子VO。
|
||||||
- **字段扩展方式:**同DTO的字段扩展方式,可以通过任意**一个**派生源BaseDTO,即可经过外键扩展成为复杂嵌套VO。只要存在外键关系且满足以下条件即可扩展:对于正向替换:当前实体存在指向其他实体的外键字段;对于反向注入:其他实体存在指向当前实体的外键字段。
|
- **字段扩展方式:**同DTO的字段扩展方式,可以通过任意**一个**派生源BaseDTO,即可经过外键扩展成为复杂嵌套VO。只要存在外键关系且满足以下条件即可扩展:对于正向替换:当前实体存在指向其他实体的外键字段;对于反向注入:其他实体存在指向当前实体的外键字段。
|
||||||
例如:有两个BaseDTO
|
例如:有两个BaseDTO
|
||||||
```
|
```
|
||||||
@@ -188,7 +243,99 @@ DateTime endTime; //会议结束时间
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- **TOCO中json结构描述:** 在TOCO中,VO使用一个json结构表示,有时用户会在上下文中提供关于DTO的json描述,所以你需要了解结构中一些关键字段,便于你能够理解用户提供的VO:expandList为正向替换,reverseExpandList为反向注入,customFieldList为自定义字段。expandListList中,field为正向替换对应的本表外键字段的名字,fieldName为正向替换之后给该字段的起的新名字;reverseExpandList中,field为反向注入对应的他表外键字段的名字,fieldName为反向注入之后给该字段的起的新名字;customFieldList中,uuid为参数对应类结构的UUID,当type为Enum、Eo时会包含该字段;innerType为List内部类型,当type为List时会包含该字段;innerUuid为List内部类结构的UUID,当type为List且innerType=Enum、Eo时会包含该字段。
|
- **TOCO中json结构描述:** 在TOCO中,VO使用一个json结构表示,该结构可用于理解VO的含义,或作为创建、更新VO工具的参数。部分字段的含义为:expandList为正向替换,reverseExpandList为反向注入,customFieldList为自定义字段。expandListList中,field为正向替换对应的本表外键字段的名字,fieldName为正向替换之后给该字段的起的新名字;reverseExpandList中,field为反向注入对应的他表外键字段的名字,fieldName为反向注入之后给该字段的起的新名字;customFieldList中,uuid为参数对应类结构的UUID,当type为Enum、Eo时会包含该字段;innerType为List内部类型,当type为List时会包含该字段;innerUuid为List内部类结构的UUID,当type为List且innerType=Enum、Eo时会包含该字段。示例如下:
|
||||||
|
- meeting_with_room_vo
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"vo": {
|
||||||
|
"uuid": null,
|
||||||
|
"name": "metting_with_room_vo",
|
||||||
|
"description": "会议详情,包含会议室信息,以及会议室禁用列表",
|
||||||
|
"isRootVo": true,
|
||||||
|
"fromEntity": "meeting",
|
||||||
|
"fromDto": "meeting_detail_dto",
|
||||||
|
"fromDtoUuid": "cd55c96b-aa67-bfb2-7614-70b503a8f8bf",
|
||||||
|
"extendFieldList":[
|
||||||
|
{
|
||||||
|
"name": "id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "title"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"expandList": [
|
||||||
|
{
|
||||||
|
"field": "room_id",
|
||||||
|
"fieldName": "meeting_room",
|
||||||
|
"vo": {
|
||||||
|
"name": "meeting_room_with_meetings_vo",
|
||||||
|
"description": "会议室信息,包含会议列表",
|
||||||
|
"isRootVo": false,
|
||||||
|
"fromEntity": "meeting_room",
|
||||||
|
"fromDto": "meeting_room_base_dto",
|
||||||
|
"fromDtoUuid": "88437212-6370-99a6-1e7a-fe1469082d08",
|
||||||
|
"reverseExpandList": [
|
||||||
|
{
|
||||||
|
"field": "room_id",
|
||||||
|
"vo": {
|
||||||
|
"name": "meeting_base_vo",
|
||||||
|
"description": "会议基本信息",
|
||||||
|
"isRootVo": false,
|
||||||
|
"fromEntity": "meeting",
|
||||||
|
"fromDto": "meeting_base_dto",
|
||||||
|
"fromDtoUuid": "1a768c5e-b449-db5d-fe55-9d572d64332a",
|
||||||
|
"extendFieldList":[
|
||||||
|
{
|
||||||
|
"name": "startTime"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "endTime"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"fieldName": "meeting_list"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"customFieldList":[
|
||||||
|
{
|
||||||
|
"name": "occupied",
|
||||||
|
"type": "Boolean",
|
||||||
|
"description": "是否被占用"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "custom_eo",
|
||||||
|
"type": "Eo"
|
||||||
|
"uuid": "uuid of an eo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "status_list",
|
||||||
|
"type": "List",
|
||||||
|
"innerType": "Enum",
|
||||||
|
"innerUuid": "uuid of an enum"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "custom_string_list",
|
||||||
|
"type": "List",
|
||||||
|
"innerType": "String"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extendFieldList":[
|
||||||
|
{
|
||||||
|
"name": "id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
示例中meeting_with_room_vo为根VO,但没有uuid,为待创建的根VO。meeting_room_with_meetings_vo和meeting_base_vo为meeting_with_room_vo的子VO,无法被其他根VO引用,且没有uuid。
|
||||||
|
|
||||||
- **派生源默认使用BaseDTO:** 除非用户指定了VO的派生源DTO,否则创建VO时只可以用**BaseDTO**为派生源。
|
- **派生源默认使用BaseDTO:** 除非用户指定了VO的派生源DTO,否则创建VO时只可以用**BaseDTO**为派生源。
|
||||||
- **与DTO的转换关系:** 在创建一个**有派生源的**VO后,TOCO会在生成代码时自动生成2种convert方法:1.基础convert方法,从DTO转换为VO,仅转换结构以及基本类型字段的get/set,方法命名为convertTo${VoName}、convertTo${VoName}List、convertTo${VoName}Map,其中**Map转换方法**为底层批量方法,通常也是自定义字段逻辑编写的位置(复用性好,会被其他convert方法调用),单个和列表convert方法都通过**调用Map方法**来实现;2.带数据拼装逻辑的convert方法,内部会**自动**调用基础convert方法从DTO转换为VO并设置基本类型字段数据,然后再根据外键**自动**获取**扩展字段**的数据以拼装最终数据,方法命名为convertAndAssembleData、convertAndAssembleDataList,也就是说这两个方法已经**自动**获取了所有**继承字段**和**扩展字段**的数据)。这2种方法对应的代码会生成在VO对应的Converter类中
|
- **与DTO的转换关系:** 在创建一个**有派生源的**VO后,TOCO会在生成代码时自动生成2种convert方法:1.基础convert方法,从DTO转换为VO,仅转换结构以及基本类型字段的get/set,方法命名为convertTo${VoName}、convertTo${VoName}List、convertTo${VoName}Map,其中**Map转换方法**为底层批量方法,通常也是自定义字段逻辑编写的位置(复用性好,会被其他convert方法调用),单个和列表convert方法都通过**调用Map方法**来实现;2.带数据拼装逻辑的convert方法,内部会**自动**调用基础convert方法从DTO转换为VO并设置基本类型字段数据,然后再根据外键**自动**获取**扩展字段**的数据以拼装最终数据,方法命名为convertAndAssembleData、convertAndAssembleDataList,也就是说这两个方法已经**自动**获取了所有**继承字段**和**扩展字段**的数据)。这2种方法对应的代码会生成在VO对应的Converter类中
|
||||||
- **字段数据获取:** 对于继承自DTO的字段、以及扩展字段,TOCO会在convert方法中自动生成数据的获取代码,无需手动实现这两种字段的获取和拼装逻辑。对于自定义字段,则**必须**在最底层的convertTo${VoName}Map方法中实现对应的获取和拼装逻辑,以便于其他convert方法都能够**复用**这段逻辑。**禁止**在其他convert方法中实现自定义字段逻辑,因为这样会导致某些场景下数据拼装不完整。
|
- **字段数据获取:** 对于继承自DTO的字段、以及扩展字段,TOCO会在convert方法中自动生成数据的获取代码,无需手动实现这两种字段的获取和拼装逻辑。对于自定义字段,则**必须**在最底层的convertTo${VoName}Map方法中实现对应的获取和拼装逻辑,以便于其他convert方法都能够**复用**这段逻辑。**禁止**在其他convert方法中实现自定义字段逻辑,因为这样会导致某些场景下数据拼装不完整。
|
||||||
|
|||||||
Reference in New Issue
Block a user