如何基于动态关系进行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中对一对多关系进行关联查询的几种方式,以及在使用过程需要注意的问题.这篇文章对多对多关系的查询处理 ...
随机推荐
- Disruptor—1.原理和使用简介
大纲 1.Disruptor简介 2.Disruptor和BlockingQueue的压测对比 3.Disruptor的编程模型 4.Disruptor的数据结构与生产消费模型 5.RingBuffe ...
- python根据日期、随机数生成编码
import datetime import random import string """ 编码格式:YYYYMMDD 身份证后四位.四位随机数 "& ...
- odoo前端的Patch用法
一.Patching code:根据官方功能解释 我们需要自定义 UI 的工作方式.一些受支持的 API 涵盖了许多常见需求. 例如,所有注册表都是很好的扩展点: 字段注册表允许添加/删除专门的字段组 ...
- 关于springboot启动时,老找不到bean
spring可以管理部分工具类,但是不可以管理接口,也就是@Controller,@Component,@Repository,@Service不能放接口上. 就相当于new一个一个实例 但是你在使用 ...
- PS简单图片拼接
1.打开图片 首先打开需要拼接的图片两张 以这两张图片为例子 首先我们先看看这两张图片的宽高分别为多少 打开图像---->画布大小 好记录下来小姐姐宽大概17cm,高大概20cm. 再来看看提莫 ...
- IOS内购数据拉取
目标:拉取app store connect 内购数据拉取,自己做数据报表. 1:api秘钥 接口需要token,token生成需要秘钥.参考官方文档:https://developer.apple. ...
- QQ号码价值评估系统html代码-丢塔网
由于前面刷视频经常刷到有人直播QQ号码价值评估,想着也搞一个玩玩,找了一圈接口好像很多都用不来,下面提供一个自己随便搞得页面,有兴趣的大佬可以完善下 ` QQ号码价值评估系统-在线工具-丢塔网(www ...
- 【6】ST表学习笔记
前言 学习ST表,主要是倍增思想,可以理解为倍增优化后的DP.写在这里,一方面方便自己以后复习,另一方面给其他人参考. UPD on 2023/3/21 :修改了格式,使格式与其他的学习笔记统一. 倍 ...
- 简单dp 二维
转载问题 http://www.cnblogs.com/moqitianliang/p/4798882.html 简要 概括动态规划 就是求原子问题,把一个问题分解成一个原子问题. 二维数组的简单 ...
- iga 入门之 区域剖分
简介 摘自 流体力学数值方法 detail 区域剖分是有限元方法在编写程序之前进行准备工作的重要一步,工作量较大. 完成如下几项 单元划分,确定结点 将求解区域(也就是积分表达式中的几分区域)划分成若 ...