在上一篇文章(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. 记录一下 nas 当本地网络存储,玩大型游戏再也不用担心硬盘不够用了

    最近由于家里的PC 在玩steam的游戏,原来1T的固态,安装了几个大型的3A游戏,一个黑神话悟空就用了200多G,硬盘就不够用了 查看了京东的2T的固态,还是很贵,要大几百块钱.去年配了一台极空间的 ...

  2. CentOS 7.* 安装最新版nginx1.28*

    一.下载nginx https://nginx.org/en/download.html 选择稳定版本 nginx-1.28.0 如果使用虚拟机,可以先用windows系统下载后,上传到虚机,此步骤省 ...

  3. 腾讯云对象存储工具类和demo

    使用 package com.ruoyi; import java.io.File; public class mytest { private static String secretId = &q ...

  4. linux系统僵尸进程处理

    查看僵尸进程 [root@mac-25 ~]# top top - 19:04:11 up 177 days, 23:58, 2 users, load average: 15.18, 21.64, ...

  5. ChatMoney,你的就业指导明灯

    本文由 ChatMoney团队出品 介绍说明 Hey!亲爱的小伙伴们,今天我要给大家带来一个职场利器--AI就业指导机器人! 在这个充满变数的职场江湖,找到一份既能养家糊口又能实现自我价值的工作是多么 ...

  6. 阿里微服务解决方案-Alibaba Cloud之服务消费方(Feign)(四)

    一.创建服务消费方并集成OpenFeign 创建模块的方式与创建服务提供方的方式一致 目录结构如下 1.1 创建完项目后,加入 OpenFeign的依赖 在父工程的 pom.xml 文件中加入如下依赖 ...

  7. Linux在线安装MySQL5.7

    Linux在线安装MySQL 5.7及编码密码修改 先检测系统是否自带安装mysql yum list installed | grep mysql 若出现mysql相关信息,卸载原始版本 yum - ...

  8. .NET Core如何通过认证机制访问Kafka?

    大家好,我是Edison. 最近有一个ASP.NET Core使用认证机制访问Kafka的需求,加之我们又使用了CAP这个开源项目使用的Kafka,于是网上寻找了一番发现对应资料太少,于是调查了一番, ...

  9. 分享一个自己在用的从K3数据库抓取数据写入EXCEL的模板。

    今天分享一个我自己在用的VBA小程序,我自己套用这个模板,解决了不同员工不同的需求. 工作中,经常遇到需要从金蝶ERP中打印一些客户需要的格式的文档,还有一些内部员工自己需要的数据做分析,如果使用K3 ...

  10. C# 动态类型 模型转XML

    <?xml version="1.0" encoding="utf-8"?> <qrylist><order orderid=&q ...