如何基于动态关系进行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中对一对多关系进行关联查询的几种方式,以及在使用过程需要注意的问题.这篇文章对多对多关系的查询处理 ...
随机推荐
- 记录一下 nas 当本地网络存储,玩大型游戏再也不用担心硬盘不够用了
最近由于家里的PC 在玩steam的游戏,原来1T的固态,安装了几个大型的3A游戏,一个黑神话悟空就用了200多G,硬盘就不够用了 查看了京东的2T的固态,还是很贵,要大几百块钱.去年配了一台极空间的 ...
- CentOS 7.* 安装最新版nginx1.28*
一.下载nginx https://nginx.org/en/download.html 选择稳定版本 nginx-1.28.0 如果使用虚拟机,可以先用windows系统下载后,上传到虚机,此步骤省 ...
- 腾讯云对象存储工具类和demo
使用 package com.ruoyi; import java.io.File; public class mytest { private static String secretId = &q ...
- linux系统僵尸进程处理
查看僵尸进程 [root@mac-25 ~]# top top - 19:04:11 up 177 days, 23:58, 2 users, load average: 15.18, 21.64, ...
- ChatMoney,你的就业指导明灯
本文由 ChatMoney团队出品 介绍说明 Hey!亲爱的小伙伴们,今天我要给大家带来一个职场利器--AI就业指导机器人! 在这个充满变数的职场江湖,找到一份既能养家糊口又能实现自我价值的工作是多么 ...
- 阿里微服务解决方案-Alibaba Cloud之服务消费方(Feign)(四)
一.创建服务消费方并集成OpenFeign 创建模块的方式与创建服务提供方的方式一致 目录结构如下 1.1 创建完项目后,加入 OpenFeign的依赖 在父工程的 pom.xml 文件中加入如下依赖 ...
- Linux在线安装MySQL5.7
Linux在线安装MySQL 5.7及编码密码修改 先检测系统是否自带安装mysql yum list installed | grep mysql 若出现mysql相关信息,卸载原始版本 yum - ...
- .NET Core如何通过认证机制访问Kafka?
大家好,我是Edison. 最近有一个ASP.NET Core使用认证机制访问Kafka的需求,加之我们又使用了CAP这个开源项目使用的Kafka,于是网上寻找了一番发现对应资料太少,于是调查了一番, ...
- 分享一个自己在用的从K3数据库抓取数据写入EXCEL的模板。
今天分享一个我自己在用的VBA小程序,我自己套用这个模板,解决了不同员工不同的需求. 工作中,经常遇到需要从金蝶ERP中打印一些客户需要的格式的文档,还有一些内部员工自己需要的数据做分析,如果使用K3 ...
- C# 动态类型 模型转XML
<?xml version="1.0" encoding="utf-8"?> <qrylist><order orderid=&q ...