实例数据
contentModel
- talent = 1
- experience = 2
- company = 3
- industry = 4
- address = 5
relation
- talent:experience = 1:n
- company:experience = 1:n
- company:industry = m:n
- company:address = 1:1
relation db data
- ContentModelRelations
{ id: 1, type: 'oneToMany', status: 'deployed' // pending deployed deleted }, { id: 2, type: 'oneToMany', status: 'deployed' }, { id: 3, type: 'manyToMany', status: 'deployed', tableName: 'Companies_Industries_202012121212' // `${tableName1}_${tableName2}_${now()}` }, { id: 4, type: 'oneToOne', status: 'deployed' } - ContentModelRelationDescriptions
{ id: 1, contentModelRelationId: 1, contentModelId: 1, foreignKey: 'talentId', alias: { contentModelId: 2, contentModelAlias: 'experiences' } }, { id: 2, contentModelRelationId: 1, contentModelId: 2, foreignKey: null, alias: { contentModelId: 1, contentModelAlias: 'talent' } }, { id: 3, contentModelRelationId: 2, contentModelId: 2, foreignKey: null, alias: { contentModelId: 3, contentModelAlias: 'company' } }, { id: 4, contentModelRelationId: 2, contentModelId: 3, foreignKey: 'companyId', alias: { contentModelId: 2, contentModelAlias: 'experiences' } }, { id: 5, contentModelRelationId: 3, contentModelId: 3, foreignKey: 'companyId', alias: { contentModelId: 4, contentModelAlias: 'industries' } }, { id: 6, contentModelRelationId: 3, contentModelId: 4, foreignKey: 'industryId', alias: { contentModelId: 3, contentModelAlias: 'companies' } }, { id: 7, contentModelRelationId: 4, contentModelId: 3, foreignKey: 'companyId', alias: { contentModelId: 5, contentModelAlias: 'address' } }, { id: 8, contentModelRelationId: 4, contentModelId: 5, foreignKey: '', alias: { contentModelId: 3, contentModelAlias: 'company' } },
- ContentModelRelations
模型关系API
- 前置
- 前端获取所有model数据
- 接口
- (前端暂时用不上)获取所有model的关系
- 请求
- status
- 响应
- 后端处理逻辑
- 通过applicationId查询ContentModelRelations和ContentModelRelationDescriptions表
- 请求
- 获取单个model的关系
- 请求
- contentModelId
- status
- 响应
- 后端处理逻辑
- 通过contentModelId查询ContentModelRelations和ContentModelRelationDescriptions表
- 请求
- 新增关系
- 请求
- 响应
- 后端处理逻辑
- (later)校验
- 1:1和1:n关系,添加在model数据表中的外键是否重复
- alias是否重复
- 把关系数据写入ContentModelRelations(status=created)和ContentModelRelationDescriptions表
- deploy时
- 执行model数据表表更
- oneToOne,在model数据表新增外键
ON DELETE SET NULL ON UPDATE CASCADE,表示一端删除时,另一端把外键的值设置为null,如果关联的主键更新,外键也同时更新
- oneToMany,在model数据表新增外键
ON DELETE SET NULL ON UPDATE CASCADE,表示一端删除时,另一端把外键的值设置为null,如果关联的主键更新,外键也同时更新
- manyToMany,新增关系表
ON DELETE CASCADE ON UPDATE CASCADE,表示任何一端删除时,把关联关系也删除,如果关联的主键更新,外键也同时更新
- oneToOne,在model数据表新增外键
- (later)更新index结构
- 计算model的mappings
- 执行reindex
- 更新ContentModelRelations中status=deployed
- 执行model数据表表更
- (later)校验
- 删除关系
- 请求
- contentModelRelationId
- 响应
- 后端处理逻辑
- 更新ContentModelRelations中status=deleted
- deploy时
- 执行model数据表表更
- 1:1或1:1关系,在model对应的数据表删除外键
- m:n关系,删除关系表
- 删除ContentModelRelations和ContentModelRelationDescriptions的关系数据
- (later)更新index结构
- 计算model的mappings
- 执行reindex
- 删除ContentModelRelations和ContentModelRelationDescriptions表对应记录
- 执行model数据表表更
- 请求
- (later)更新关系
- 请求
- 响应
- 后端处理逻辑
- foreignKey更新
- 执行model数据表表更
- 对model数据表分别执行alter:删除外键约束、更新外键字段名、重新添加外键约束
- 更新ContentModelRelationDescriptions的关系数据
- 执行model数据表表更
- alias更新
- 更新ContentModelRelationDescriptions的关系数据
- (later)更新index结构
- 计算model的mappings
- 执行reindex
- foreignKey更新
- (前端暂时用不上)获取所有model的关系
模型数据API(CMS)
- 前置
- 前端请求
api/models/${contentModelId}?withRelationFields=true获取当前model的所有fields以及relationFields- ContentModelFields中的数据
{ contentModelFields: [ { id: 1, labelName: 'id', fieldName: 'id' }, { id: 2, labelName: 'Company Name', fieldName: 'companyName' }, ... ], relationFields: [ { fieldName: 'experiences', type: 'oneToMany', /* type=oneToMany时,如果foreignKey!=null,表示是oneToMany关系的左侧,否则为右侧,关系到是否允许设置多个值 */ alias: { contentModelId: 2, mainField: 'title', contentModelAlias: 'experiences' }, /* alias结构为ContentModelRelationDescriptions中的alias结构,只不过多插入了一个mainField,为当前model里面isEntityTitle=true的字段的fieldName; 前端后续在设置关联数据时,通过拼contentModelId来拉取对应model的数据 */ foreignKey: 'talentId', aliases: [ { contentModelId: 6, mainField: 'zzz', contentModelAlias: 'xxxx' }, { contentModelId: 7, mainField: 'zzz', contentModelAlias: 'xxx' } ] /* aliases字段只是针对m:n(>2)的场景,前端需要根据relationType='manyToMany' && !!aliases来判断当前关系是是m:n(>2) */ }, { fieldName: 'industries', type: 'manyToMany', alias: { contentModelId: 4, mainField: 'name', alias: 'industries' }, foreignKey: 'companyId' }, { fieldName: 'address', type: 'oneToOne', alias: { contentModelId: 5, mainField: 'city', alias: 'address' }, foreignKey: 'companyId' } ] }
- ContentModelFields中的数据
- 前端请求
- 接口
- 获取单页数据
- 请求
api/models/${contentModelId}/data接口- contentModelId
- page
- limit
- withRelationData=true
- 表示把关系的模型数据一起返回
- (later)默认情况下,关系中的模型数据只会返回id+isEntityTitle的字段,如果后续需要返回全部字段数据再加配置支持
- (later)keyword
- 仅针对isEntityTitle字段做搜索
- 响应
[ { id: 1, companyName: 'Google', createdAt: '2019-12-01', experiences: [ { id: 1, title: 'ceo' }, { id: 2, title: 'coo' }, { id: 3, title: 'cfo' } ], industries: [ { id: 1, name: 'it' }, { id: 2, name: 'finance' }, { id: 3, name: 'food' } ], address: { id: 1, city: 'NY' } }, ... ] - 后端处理逻辑
- 获取当前model的关系,以及关系关联的其他model数据
- 根据关联关系拼接sql
- 组装数据,外键关联的数据组织成alias子字段的方式
- 获取当前model的关系,以及关系关联的其他model数据
- 请求
- (前端好像暂时用不上)获取单条数据
- 请求
- contentModelId
- id(数据id)
- withRelationData=true
- 表示把关系的模型数据一起返回;默认情况下,关系中的模型数据只会返回id+isEntityTitle的字段,如果后续需要返回全部字段数据再加配置支持
- 响应
{ id: 1, companyName: 'Google', createdAt: '2019-12-01', experiences: [ { id: 1, title: 'ceo' }, { id: 2, title: 'coo' }, { id: 3, title: 'cfo' } ], industries: [ { id: 1, name: 'it' }, { id: 2, name: 'finance' }, { id: 3, name: 'food' } ], address: { id: 1, city: 'NY' } } - 后端处理逻辑
- 获取当前model的关系,以及关系关联的其他model数据
- 根据关联关系拼接sql
- 组装数据,外键关联的数据组织成alias子字段的方式
- 获取当前model的关系,以及关系关联的其他model数据
- 请求
- 插入单条数据
- 请求,POST
api/models/${contentModelId}/data{ companyName: 'Google', createdAt: '2019-12-01', experiences: [ { id: 1, title: 'ceo' }, { id: 2, title: 'coo' }, { id: 3, title: 'cfo' } ], industries: [ { id: 1, name: 'it' }, { id: 2, name: 'finance' }, { id: 3, name: 'food' } ], address: { id: 1, city: 'NY' }, ... } - 响应
- 后端处理逻辑
- 获取当前model的关系,以及关系关联的其他model数据
- 遍历并处理所有字段
- 字段为model本身的字段,拼接到sql insert语句中,遍历完成后执行
- 字段为关系中的alias字段
- 关系 = 1:1或1:n,且当前model保存外键的model
- 更新model数据表外键字段
- 关系 = 1:1或1:n,且当前model不保存外键
- 更新对侧model数据表的外键字段
- 关系 = m:n
- 插入关系数据表
- ** 插入index数据
- 插入关系数据表
- 关系 = 1:1或1:n,且当前model保存外键的model
- 请求,POST
- 更新单条数据
- 请求,PUT
api/models/${contentModelId}/data{ id: 1, companyName: 'Google', createdAt: '2019-12-01', experiences: [ { id: 1, title: 'ceo' }, { id: 2, title: 'coo' }, { id: 3, title: 'cfo' } ], industries: [ { id: 1, name: 'it' }, { id: 2, name: 'finance' }, { id: 3, name: 'food' } ], address: { id: 1, city: 'NY' } ... } - 响应
- 后端处理逻辑
- 获取当前model的关系,以及关系关联的其他model数据
- 遍历并处理所有字段
- 字段为model本身的字段,拼接到sql update语句中,遍历完成后执行
- 字段为关系中的alias字段
- 关系 = 1:1或1:n,且当前model保存外键的model
- 查询现有关联数据,如果有更新,则更新model数据表外键字段
- 关系 = 1:1或1:n,且当前model不保存外键,则更新对侧model数据表的外键字段
- 查询现有关联数据,如果不同,则执行删除或新增关系的外键更新
- 关系 = m:n
- 查询现有关联数据,如果不同,则执行删除或新增关系的外键更新
- ** 更新index数据
- 查询现有关联数据,如果不同,则执行删除或新增关系的外键更新
- 关系 = 1:1或1:n,且当前model保存外键的model
- 请求,PUT
- 删除单条数据
- 请求,DELETE
api/models/${contentModelId}/data- id(数据id)
- 响应
- 后端处理逻辑
- 执行sql delete
- 由于设置了外键约束,在一对多和一对一关系中,被删除数据关联的外键会自动设置为NULL
- 如果是多对多关系,关系表中的关系数据会自动删除
- 执行sql delete
- 请求,DELETE
- 获取单页数据