如何基于动态关系进行ORM关联查询,并动态推断DTO?
在上一篇文章(Prisma不能优雅的支持DTO,试试Vona ORM吧)中,我们基于静态关系实现了目录树
的关联查询,并且动态推断生成了DTO(用于Swagger元数据)。在这篇文章我们探讨动态关系
的用法。
什么是动态关系
那么,什么是动态关系呢?在大型业务系统中,我们会创建大量数据模型,这些数据模型之间的关联众多,我们不可能将所有关联通过静态关系
的机制事先声明出来。特别是当存在大量业务模块,这些数据模型散落在不同的业务模块中,那么通过静态关系
事先声明所有的关联关系也变得不太现实。比如,Prisma就只支持静态关系
。如果事先没有定义静态关系
,在实际代码中,我们就需要提供一种使用动态关系
的机制,让我们的查询、类型推断、DTO推断等能力得以正常使用。
准备数据模型
在上一篇文章中,我们已经介绍了如何创建Entity和Model,这里不再赘述。而是直接把Order和Customer的Entity和Model罗列出来,然后演示动态关系
的用法
Entity
1. Order
@Entity()
export class EntityOrder extends EntityBase {
@Api.field(v.openapi({ title: $locale('OrderNo') }), v.default(''), v.min(3))
orderNo: string;
@Api.field(v.title($locale('Remark')), v.optional())
remark?: string;
@Api.field(v.tableIdentity())
customerId: TableIdentity;
}
- v.openapi:声明字段的元数据,用于Swagger
- title:采用$locale定义,从而让Swagger元数据支持多语言能力
- v.title:等价于v.openapi({ title: ... })
- TableIdentity:string | number
2. Customer
@Entity()
export class EntityCustomer extends EntityBase {
@Api.field(v.min(3))
name: string;
}
Model
1. Order
@Model({ entity: EntityOrder })
export class ModelOrder extends BeanModelBase {}
2. Customer
@Model({ entity: EntityCustomer })
export class ModelCustomer extends BeanModelBase {}
基于动态关系
的查询
现在我们查询订单列表,包含归属的顾客信息:
const orders = await this.scope.model.order.select({
with: {
customer: $relationDynamic.belongsTo(
() => ModelOrder,
() => ModelCustomer,
'customerId',
),
},
});
- $relationDynamic:提供一组工具,用于定义动态关系
- belongsTo:定义
多对一
的关系- 参数1:Order模型
- 参数2:Customer模型
- 参数3:设置关联外键customerId
下面我们看一下orders
的类型推断效果:
自动推断DTO
现在我们自动推断DTO,并且设为API的返回数据的类型:
const DtoOrderResult = $Dto.get(
() => ModelOrder,
{
with: {
customer: $relationDynamic.belongsTo(
() => ModelOrder,
() => ModelCustomer,
'customerId',
),
},
},
);
@Controller('order')
export class ControllerOrder extends BeanBase {
@Web.get()
@Api.body(v.array(v.object(DtoOrderResult)))
async findAll() {
return await this.scope.service.order.findAll();
}
}
- 行1:动态创建
DtoOrderResult
- 行17:将
DtoOrderResult
用于Swagger/Openapi的元数据
下面我们看一下API的Swagger效果:
封装DTO
我们还可以创建一个新的DTO,将前面动态创建的DtoOrderResult
封装起来,从而用于其他地方:
在VSCode中,可以通过右键菜单Vona Create/Dto
创建DTO的代码骨架:
@Dto()
export class DtoOrderResult {}
然后我们通过继承机制来封装DTO:
const DtoOrderResultDynamic = $Dto.get(
() => ModelOrder,
{
with: {
customer: $relationDynamic.belongsTo(
() => ModelOrder,
() => ModelCustomer,
'customerId',
),
},
},
);
@Dto()
export class DtoOrderResult extends DtoOrderResultDynamic {}
现在,我们再使用新创建的DTO来改造前面的API代码:
+ import { DtoOrderResult } from '../dto/orderResult.ts';
@Controller('order')
export class ControllerOrder extends BeanBase {
@Web.get()
+ @Api.body(v.array(v.object(DtoOrderResult)))
+ async findAll(): Promise<DtoOrderResult[]> {
return await this.scope.service.order.findAll();
}
}
- 行6: 直接传入
DtoOrderResult
- 行7: 返回类型为
Promise<DtoOrderResult[]>
结语
Vonajs已开源:https://github.com/vonajs/vona。
Vonajs作者正在B站直播撰写技术文档,工作日每晚8:30,欢迎围观:濮水代码直播间
如何基于动态关系进行ORM关联查询,并动态推断DTO?的更多相关文章
- MyBatis学习总结(三)——多表关联查询与动态SQL
在上一章中我们学习了<MyBatis学习总结(二)——MyBatis核心配置文件与输入输出映射>,这一章主要是介绍一对一关联查询.一对多关联查询与动态SQL等内容. 一.多表关联查询 表与 ...
- Mybatis之关联查询及动态SQL
前言 实际开发项目中,很少是针对单表操作,基本都会联查多表进行操作,尤其是出一些报表的内容.此时,就可以使用Mybatis的关联查询还有动态SQL.前几篇文章已经介绍过了怎么调用及相关内容,因此这里只 ...
- beego中orm关联查询使用解析
这两天在学习beego框架,之前学习的时候遗漏了很多东西,比如orm.缓存.应用监控.模板处理等,这里将通过实例记录下如何使用beego自带的orm进行关联查询操作. 首先说明下,beego的orm有 ...
- 基于EF的数据外键关联查询
现在很多ORM不自带外键关联的实体查询,比如我查询用户,用时将关联的角色信息查询出来,那么就要进行2次查询,很麻烦.而我现在要做的就是基于EF的外键关联查询.很方便的. 首先,创建基础查询的BaseS ...
- [转]NHibernate之旅(11):探索多对多关系及其关联查询
本节内容 多对多关系引入 多对多映射关系 多对多关联查询 1.原生SQL关联查询 2.HQL关联查询 3.Criteria API关联查询 结语 多对多关系引入 让我们再次回顾在第二篇中建立的数据模型 ...
- NHibernate教程(11)--多对多关联查询
本节内容 多对多关系引入 多对多映射关系 多对多关联查询 1.原生SQL关联查询 2.HQL关联查询 3.Criteria API关联查询 结语 多对多关系引入 让我们再次回顾在第二篇中建立的数据模型 ...
- JAVA入门[9]-mybatis多表关联查询
概要 本节要实现的是多表关联查询的简单demo.场景是根据id查询某商品分类信息,并展示该分类下的商品列表. 一.Mysql测试数据 新建表Category(商品分类)和Product(商品),并插入 ...
- MyBatis 实践 -动态SQL/关联查询
MyBatis 实践 标签: Java与存储 动态SQL 动态SQL提供了对SQL语句的灵活操作,通过表达式进行判断,对SQL进行拼接/组装. if 对查询条件进行判断,如果输入参数不为空才进行查询条 ...
- Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终端打印SQL语句,脚本调试)
Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终 ...
- [NHibernate]多对多关系(关联查询)
目录 写在前面 文档与系列文章 多对多关系关联查询 总结 写在前面 上篇文章介绍了nhibernate中对一对多关系进行关联查询的几种方式,以及在使用过程需要注意的问题.这篇文章对多对多关系的查询处理 ...
随机推荐
- 重磅消息,微软宣布 VS Code Copilot 开源,剑指 Cursor!
前言 微软宣布重磅消息将把 GitHub Copilot Chat 扩展的代码以 MIT 许可证协议开源,然后将扩展中的 AI 功能重构到 VS Code 核心中,这一举措是为了将 VS Code 成 ...
- Win32汇编学习笔记04.重定位与汇编引擎
Win32汇编学习笔记04.重定位与汇编引擎-C/C++基础-断点社区-专业的老牌游戏安全技术交流社区 - BpSend.net 重定位 **重定位:**也称为代码自重定位,代码自己去计算自己使用的各 ...
- Vue3中Mock数据的简单方案
因为Vue3项目开发中需要用到Mock数据,所以这里记录一种快速Mock数据的方法. 一.安装 首先,你需要安装 axios 和 axios-mock-adapter. npm install axi ...
- DotTrace系列:5. 诊断程序的 慢File 和 慢SQL
一:背景 1. 讲故事 上一篇跟大家聊到了 UI Freeze 的问题,让大家感受到了时间轴的强大和美观,这个是 perfview 所不具备的,本篇跟大家聊一下用 dottrace 诊断Windows ...
- Kamailio SIP+RTP双网卡SBC呼叫流程与媒体处理说明
本文档旨在详细解释基于提供的 kamailio_sbc_dual_nic.cfg 配置文件,在双网卡SBC(Session Border Controller)场景下,Kamailio (5.8.3) ...
- PHP指定编码
header("Content-type: text/html; charset=utf-8");
- 局域网内使用UDP广播方式搜索wifi模块的使用说明
局域网内搜索接入路由器的WIFI模块的IP地址和MAC地址. 搜索模块发送UDP数据包返回模块ip和mac地址. 局域网内搜索,确定模块接入无线路由器后的IP. 如上图所示,模块作为STA链接 ...
- React Hooks中memo、useMemo、useCallBack的作用
一句话概括 memo.useMemo.useCallBack主要用于避免 React 组件的重复渲染,作为 性能优化 的一种手段,你可以根据场景合理的使用它们. React组件的更新机制 在使用mem ...
- 2021牛客寒假算法基础集训营1 ABFI 题解
A 题意:问你含有us子序列的,长度不大于n的串有多少(都是小写字母) 思路:其实每个位置可填放的字符就三种, u,s,和其他24个字符. 由于要求含有us子序列的串比较麻烦,正难则反,我们可以先求出 ...
- Codeforces Round #693 (Div. 3) ABCDE题解
A. Cards for Friends 思路:折纸游戏,看长宽能各折多少次,就是2的几次方,相乘即可. view code #include<iostream> #include< ...