当前位置: 首页 > 工具软件 > QueryBuilder > 使用案例 >

在 NestJS 中使用 TypeORM 的 QueryBuilder

邹修真
2023-12-01

NestJS是一个相对较新的 JavaScript Web 框架,使您能够构建企业级的服务器端应用程序。它功能强大,强制执行最佳实践,并使用最新的 JavaScript 功能。它还默认支持 TypeScript 并使用TypeORM,这是一个使用 TypeScript 构建的强大的对象关系管理库。

TypeORM 在 GitHub 上拥有超过29.3k 颗星,是最受欢迎的 Node.js ORM 之一。除了与数据库无关之外,TypeORM 还有一个独特的 API,允许您使用 Active Record 和 Data Mapper 模式以不同的方式访问 SQL 数据库(如 MYSQL 和 PostgreSQL)和 NoSQL 数据库(如 MongoDB)中的数据。

在这篇文章中,我们将学习如何将 TypeORM 与 NestJS 集成,添加数据库驱动程序,并在 NestJS 中使用 TypeORM QueryBuilder 运行基本查询。

要有效地阅读本文,您应该具备:

  • 在您的计算机上安装Node.js v12 LTS 或 Node >v14 — NVM使在不同版本的 Node.js 之间切换变得更加容易

  • NestJS和JavaScript的基本工作知识

需要复习一些基础知识吗?查看这篇关于使用 NestJS 构建电子商务应用程序的实用文章。

让我们开始吧!

目录

  • 设置 NestJS

    • 生成基本应用设置

    • 使用 SQLite 配置 TypeORM

    • 创建数据库实体

  • 在 NestJS 中使用 TypeORM QueryBuilder 运行基本查询

  • 在带有NestJSJOIN的 TypeORM 查询中使用

    • 使用find选项

    • 使用 QueryBuilderJOIN

设置 NestJS 很简单,有几种方法可以做到,具体取决于您的需要。但是,在本文中,我们将使用 CLI 安装它。

npx @nestjs / cli @9 。0.0新巢-应用

这个命令将搭建 NestJS “Hello, World!” 样板应用程序,因此您可以直接潜入并开始编码。

现在我们已经安装了 NestJS,让我们将 TypeORM 集成到我们的应用程序中。密切关注本节;在开始编写查询之前,您需要正确集成 TypeORM。

在您的终端上运行此命令以安装 TypeORM 和 SQLite3 驱动程序——我们将在本教程中使用 SQLite 来降低安装和设置 MySQL 或 PostgreSQL 数据库的复杂性。


超过 20 万开发人员使用 LogRocket 来创造更好的数字体验了解更多 →


npm install @nestjs / typeorm sqlite3

生成基本应用设置

接下来,让我们使用 NestJS CLI 为我们的查询应用程序的框架生成控制器和服务。运行以下命令生成它并选择 REST API 传输层。

npx @nestjs / cli @9 。0.0 g 资源帖

它将询问您是否要生成 CRUD 入口点。选择是。为您生成所有内容需要一点时间,但这是 NestJS 的有用方面之一。

使用 SQLite 配置 TypeORM

现在,让我们在文件中配置 TypeORM 。src/app.module.ts

最初,它看起来像这样:

// src/app.module.ts import { Module } from '@nestjs/common' ; 从'./app.controller'导入{ AppController } ;从'./app.service'导入{ AppService } ;从'./posts/posts.module'导入{ PostsModule } ;@Module ({
  导入:[ PostsModule ],
  控制器:[ AppController ],
  提供者:[ AppService
     
     
     
     
   ], })导出类AppModule {}
​
  

导入 SQLite 连接选项、TypeORM 模块和 post 实体,如下代码所示:

// src/app.module.ts import { Module } from '@nestjs/common' ; 从'@nestjs/typeorm'导入{ TypeOrmModule } ;从'typeorm/driver/sqlite/SqliteConnectionOptions'导入{ SqliteConnectionOptions } ;从'./app.controller'导入{ AppController } ;从'./app.service'导入{ AppService } ;从'./posts/entities/post.entity'导入{帖子}
     
     
     
     
     
     ; 从'./posts/posts.module'导入{ PostsModule } ;
     
​
常量配置:SqliteConnectionOptions = {
  类型:“sqlite” ,
  数据库:“../db” ,
  实体:[发布],
  同步:真}       
​
​
@Module ( {
  导入:[ PostsModule , TypeOrmModule .forRoot ( config )],
  控制器:[ AppController ],
  提供者:[ AppService ],})导出类AppModule {}    
​
  

现在,让我们完成我们刚刚添加的更新。首先,查看配置对象的形状,我们添加了数据库和实体并同步了数据库。但是,重要的是要记住,在生产环境中同步数据库不是您应该做的事情,因为它可能会导致数据丢失。

// 配置const config : SqliteConnectionOptions = { 
  type : "sqlite" , 
  database : "../db" , 
  entity : [ Post ], 
  synchronize : true // 在生产环境中设置为 false }
        

因为我们使用的是 SQLite 数据库,所以我们可以使用. 如果它不存在,它将自动为您创建。对于 MySQL 或 PostgreSQL,形状不同,因此请查看文档以了解更多信息。"../db",


来自 LogRocket 的更多精彩文章:

  • 不要错过来自 LogRocket 的精选时事通讯The Replay

  • 使用 React 的 useEffect优化应用程序的性能

  • 在多个 Node 版本之间切换

  • 了解如何使用 AnimXYZ 为您的 React 应用程序制作动画

  • 探索 Tauri,一个用于构建二进制文件的新框架

  • 比较NestJS 与 Express.js

  • 发现TypeScript 领域中使用的流行 ORM


创建数据库实体

实体是数据库模型,在我们的例子中,我们的Post实体有一个 ID 和一个标题,如下面的代码所示:

// src/post/entities/post.entity.ts import { Column , Entity , PrimaryGeneratedColumn } from "typeorm" ; @Entity ()导出类Post { @PrimaryGeneratedColumn () 
    id : number ; @Column ()
    标题:字符串;}
       
​
   
    
    

最后,在通用应用 TypeORM 设置中,让我们将 TypeORM 配置与 NestJS 挂钩。请注意该方法,因为您在设置功能级别配置时可能会看到类似的内容。.forRoot

进口:[ PostsModule ,TypeOrmModule 。forRoot (配置)] ,  

在这里,我们将 TypeORM 与 NestJS 挂钩。接下来,让我们将我们的Post功能与 ORM 集成。

导航到该文件并使用以下配置对其进行更新:src/posts/posts.module.ts

// src/posts/posts.module.ts import { Module } from '@nestjs/common' ; 从'./posts.service'导入{ PostsService } ;从'./posts.controller'导入{ PostsController } ;@Module ({ 
  controllers : [ PostsController ], 
  providers : [ PostsService ] })导出类PostsModule {}
     
     
     
  
​
  

接下来,导入 TypeORM,Post实体,并通过设置模块导入的值来更新代码。请注意,我们使用并传入了一组实体,而不是应用级模块配置。[TypeOrmModule.forFeature([Post])]``forFeature

从'@nestjs/common'导入{模块} ;从'./posts.service'导入{ PostsService } ;从'./posts.controller'导入{ PostsController } ;从'@nestjs/typeorm'导入{ TypeOrmModule } ;从'./entities/post.entity'导入{帖子} ;@Module ({
  进口: [ TypeOrmModule . forFeature ([ Post     
     
     
     
     
 ])],
  控制器:[ PostsController ],
  提供者:[ PostsService ] })导出类PostsModule {}  
​
  

在 NestJS 中使用 TypeORM QueryBuilder 运行基本查询

有几种方法可以使用 TypeORM 和 NestJS 访问数据库,包括使用 Repository API、Entity Manager API 和使用 DataSource API。

下面是一个快速示例,说明如何使用上述 API 按 ID 获取项目。我已经删除了与本示例无关的大部分代码,但您可以在GitHub 上找到完整的代码。

//src/posts/posts.service.ts
​
@Injectable ()导出类PostsService {
   
​
  构造函数(@InjectRepository ( Post ) private postRepository : Repository < Post >, @InjectEntityManager () private postManager : EntityManager , @InjectDataSource () private dataSource : DataSource ) { }
      
      
      
    
​
  异步findOne ( id : number ) { 
​
    const postWithRepository =等待这个。后存储库。findOneBy ({ id });  
​
    const postWithRepositoryQueryBuilder =等待这个。后存储库
      。createQueryBuilder (“发布” )。其中(“post.id=:postId” ,{ postId :id })。得到一个()  
       
      
​
    const postWithEntityManager = await this.postManager
      .createQueryBuilder(Post, "post")
      .where("post.id= :postId", { postId: id })
      .getOne()
​
    const postWithDataSource = await this.dataSource
      .createQueryBuilder()
      .select("post")
      .from(Post, "post")
      .where("post.id= :postId", { postId: id })
      .getOne()
​
    return {
      postWithRepository,
      postWithRepositoryQueryBuilder,
      postWithEntityManager,
      postWithDataSource
    };
  }
​
}

如您所见,我们在构造函数中初始化了数据访问层,然后在方法中使用它们。

//src/posts/posts.service.ts ...构造函数( @InjectRepository ( Post ) private postRepository : Repository < Post >, ) { } ...
​
​
      
    

除此之外,其余代码只是普通的 TypeORM 查询;您可以通过查看他们的文档来更深入地了解 TypeORM 。

上述代码中的所有查询都将返回相同的结果。那么,有几种方法可以实现一个目标,但哪种方法最有效呢?

在处理小型数据集时,这两种方法的表现相似。但是,我发现在处理具有多个关系的大型数据集时,QueryBuilder API 比存储库查询更有效。我相信这是因为QueryBuilder API比Repository API 更接近原始 SQL 查询。

JOIN在带有 NestJS 的 TypeORM 中使用查询

如果您编写的 SQL 查询涉及使用 SQL 从多个表中访问数据,那么您之前可能已经编写过JOIN查询。JOIN查询允许您一次从多个表中查询数据。让我们看一下LEFT JOINTypeORM 中的一个操作。这种类型的查询将返回左表中的所有行和右表中的匹配行。

LEFT JOIN在 TypeORM中执行操作有多种方法。让我们来看看其中的一些:

  • 使用find选项

  • 使用查询构建器

尽管我们的重点是使用 QueryBuilder,但我将向您展示一个使用这两个选项的示例,以便您了解两者之间的差异。

下面我们来看看这个SQLLEFT JOIN操作。我们将其转换为使用find选项和 TypeORM 的 QueryBuilder 方法。

SELECT  * FROM "user" LEFT JOIN "courses" "course" ON "course"。“id” = “用户”。"courseId" WHERE "课程"。"name" = 'JavaScript Fundamentals' AND "course"。“长度” = '8 小时'  
       
      

find在 TypeORM 中使用

用户存储库。查找({关系:{课程:真},其中:{课程:{名称:“JavaScript基础”,长度:“8小时” },},})
       
   
Windows软件安装器,纯绿色版无需安装,傻瓜一键还原无需激活!    

上面的代码是LEFT JOIN使用 TypeORMfind选项的查询。幸运的是,这很简单,因为 TypeORM 会为您找出最好JOIN的并为您提供适当的结果。现在,让我们使用 TypeORM QueryBuilder 实现上述查询。

使用 QueryBuilderJOIN

常量用户=这个。用户管理器
      。createQueryBuilder (用户,“用户” )。leftJoin (“课程” 。“id” ,“课程” )。where ( "course.name = :name" , { name : "JavaScript Fundamentals" }) 。andWhere ( "course.length = :length" , { length : "8 hours" })  
       
         
        

使用 QueryBuilder 时,您还可以选择不同类型JOINS的find.

以下是TypeORM 中可用的一些附加功能。JOINS

结论

如果您希望在不影响质量的情况下快速构建可靠的后端,请考虑使用 TypeORM。在本文中,我们学习了如何将 TypeORM QueryBuilder 与 NestJS 集成和使用,但我们只触及了使用 TypeORM 可以做什么的皮毛。查看 TypeORM 文档以了解更多信息。

快乐黑客!

LogRocket主动显示和诊断您的应用程序和网站中最重要的问题

成千上万的工程和产品团队使用LogRocket来减少了解技术和可用性问题的根本原因所需的时间。使用 LogRocket,您将减少与客户来回对话的时间,并消除无休止的故障排除过程。LogRocket 让您可以花更多时间构建新事物,而减少修复错误的时间。

 类似资料: