在上一篇文章(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?的更多相关文章

  1. MyBatis学习总结(三)——多表关联查询与动态SQL

    在上一章中我们学习了<MyBatis学习总结(二)——MyBatis核心配置文件与输入输出映射>,这一章主要是介绍一对一关联查询.一对多关联查询与动态SQL等内容. 一.多表关联查询 表与 ...

  2. Mybatis之关联查询及动态SQL

    前言 实际开发项目中,很少是针对单表操作,基本都会联查多表进行操作,尤其是出一些报表的内容.此时,就可以使用Mybatis的关联查询还有动态SQL.前几篇文章已经介绍过了怎么调用及相关内容,因此这里只 ...

  3. beego中orm关联查询使用解析

    这两天在学习beego框架,之前学习的时候遗漏了很多东西,比如orm.缓存.应用监控.模板处理等,这里将通过实例记录下如何使用beego自带的orm进行关联查询操作. 首先说明下,beego的orm有 ...

  4. 基于EF的数据外键关联查询

    现在很多ORM不自带外键关联的实体查询,比如我查询用户,用时将关联的角色信息查询出来,那么就要进行2次查询,很麻烦.而我现在要做的就是基于EF的外键关联查询.很方便的. 首先,创建基础查询的BaseS ...

  5. [转]NHibernate之旅(11):探索多对多关系及其关联查询

    本节内容 多对多关系引入 多对多映射关系 多对多关联查询 1.原生SQL关联查询 2.HQL关联查询 3.Criteria API关联查询 结语 多对多关系引入 让我们再次回顾在第二篇中建立的数据模型 ...

  6. NHibernate教程(11)--多对多关联查询

    本节内容 多对多关系引入 多对多映射关系 多对多关联查询 1.原生SQL关联查询 2.HQL关联查询 3.Criteria API关联查询 结语 多对多关系引入 让我们再次回顾在第二篇中建立的数据模型 ...

  7. JAVA入门[9]-mybatis多表关联查询

    概要 本节要实现的是多表关联查询的简单demo.场景是根据id查询某商品分类信息,并展示该分类下的商品列表. 一.Mysql测试数据 新建表Category(商品分类)和Product(商品),并插入 ...

  8. MyBatis 实践 -动态SQL/关联查询

    MyBatis 实践 标签: Java与存储 动态SQL 动态SQL提供了对SQL语句的灵活操作,通过表达式进行判断,对SQL进行拼接/组装. if 对查询条件进行判断,如果输入参数不为空才进行查询条 ...

  9. Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终端打印SQL语句,脚本调试)

    Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终 ...

  10. [NHibernate]多对多关系(关联查询)

    目录 写在前面 文档与系列文章 多对多关系关联查询 总结 写在前面 上篇文章介绍了nhibernate中对一对多关系进行关联查询的几种方式,以及在使用过程需要注意的问题.这篇文章对多对多关系的查询处理 ...

随机推荐

  1. Disruptor—1.原理和使用简介

    大纲 1.Disruptor简介 2.Disruptor和BlockingQueue的压测对比 3.Disruptor的编程模型 4.Disruptor的数据结构与生产消费模型 5.RingBuffe ...

  2. python根据日期、随机数生成编码

    import datetime import random import string """    编码格式:YYYYMMDD 身份证后四位.四位随机数 "& ...

  3. odoo前端的Patch用法

    一.Patching code:根据官方功能解释 我们需要自定义 UI 的工作方式.一些受支持的 API 涵盖了许多常见需求. 例如,所有注册表都是很好的扩展点: 字段注册表允许添加/删除专门的字段组 ...

  4. 关于springboot启动时,老找不到bean

    spring可以管理部分工具类,但是不可以管理接口,也就是@Controller,@Component,@Repository,@Service不能放接口上. 就相当于new一个一个实例 但是你在使用 ...

  5. PS简单图片拼接

    1.打开图片 首先打开需要拼接的图片两张 以这两张图片为例子 首先我们先看看这两张图片的宽高分别为多少 打开图像---->画布大小 好记录下来小姐姐宽大概17cm,高大概20cm. 再来看看提莫 ...

  6. IOS内购数据拉取

    目标:拉取app store connect 内购数据拉取,自己做数据报表. 1:api秘钥 接口需要token,token生成需要秘钥.参考官方文档:https://developer.apple. ...

  7. QQ号码价值评估系统html代码-丢塔网

    由于前面刷视频经常刷到有人直播QQ号码价值评估,想着也搞一个玩玩,找了一圈接口好像很多都用不来,下面提供一个自己随便搞得页面,有兴趣的大佬可以完善下 ` QQ号码价值评估系统-在线工具-丢塔网(www ...

  8. 【6】ST表学习笔记

    前言 学习ST表,主要是倍增思想,可以理解为倍增优化后的DP.写在这里,一方面方便自己以后复习,另一方面给其他人参考. UPD on 2023/3/21 :修改了格式,使格式与其他的学习笔记统一. 倍 ...

  9. 简单dp 二维

    转载问题 http://www.cnblogs.com/moqitianliang/p/4798882.html 简要 概括动态规划  就是求原子问题,把一个问题分解成一个原子问题. 二维数组的简单 ...

  10. iga 入门之 区域剖分

    简介 摘自 流体力学数值方法 detail 区域剖分是有限元方法在编写程序之前进行准备工作的重要一步,工作量较大. 完成如下几项 单元划分,确定结点 将求解区域(也就是积分表达式中的几分区域)划分成若 ...