当前位置: 首页 > news >正文

NestJS 手动集成TypeORM

简介

TypeORM 是 Node.js 生态中最成熟、功能最全面的对象关系映射(ORM)框架之一。由于其本身就是使用 TypeScript 编写,因此与 NestJS 框架的集成非常自然且高效。

快速开始

1. 安装依赖

首先,需要安装 TypeORM 及其对应的数据库驱动(以 MySQL 为例):

npm install --save typeorm mysql2

💡 提示:如果您使用的是 PostgreSQL,请安装 pg 包;使用 SQLite,则安装 sqlite3

2. 建立数据库连接

我们需要使用 TypeORM 的 DataSource 类来建立与数据库的连接。DataSource.initialize() 方法返回一个 Promise,因此在 NestJS 中必须使用异步提供者(Async Provider) 来处理。

创建 database.providers.ts 文件:

// database.providers.ts
import { DataSource } from 'typeorm';export const databaseProviders = [{provide: 'DATA_SOURCE', // 自定义令牌,用于依赖注入useFactory: async () => {const dataSource = new DataSource({type: 'mysql',           // 数据库类型host: 'localhost',       // 主机地址port: 3306,              // 端口username: 'root',        // 用户名password: 'root',        // 密码database: 'test',        // 数据库名entities: [__dirname + '/../**/*.entity{.ts,.js}', // 自动加载实体文件],synchronize: true,       // 开发环境可用,生产环境禁用!});return dataSource.initialize(); // 初始化连接},},
];

⚠️ 警告synchronize: true 会在应用启动时自动根据实体同步数据库表结构。此选项绝不能在生产环境中使用,否则可能导致生产数据丢失。

💡 最佳实践:将自定义提供者定义在独立的 *.providers.ts 文件中。

3. 创建 DatabaseModule

将数据库提供者导出,以便其他模块可以使用。

创建 database.module.ts 文件:

// database.module.ts
import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';@Module({providers: [...databaseProviders],exports: [...databaseProviders], // 导出提供者,使其可被其他模块注入
})
export class DatabaseModule {}

💡 说明DATA_SOURCE 是一个异步提供者。任何依赖它的服务或模块都会等待其 Promise 解析完成后再被实例化,NestJS 会自动处理这种依赖延迟。

使用仓储模式(Repository Pattern)

TypeORM 支持仓储设计模式,每个实体都有其对应的仓储(Repository),用于执行数据库操作。

1. 创建实体(Entity)

首先,定义一个实体。以下以官方文档中的 Photo 实体为例:

// photo.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';@Entity()
export class Photo {@PrimaryGeneratedColumn()id: number;@Column({ length: 500 })name: string;@Column('text')description: string;@Column()filename: string;@Column('int')views: number;@Column()isPublished: boolean;
}

💡 此 Photo 实体通常位于 photo 目录下,该目录代表一个 PhotoModule

2. 创建仓储提供者

Photo 实体创建一个仓储提供者,该提供者依赖于前面创建的 DATA_SOURCE

创建 photo.providers.ts 文件:

// photo.providers.ts
import { DataSource } from 'typeorm';
import { Photo } from './photo.entity';export const photoProviders = [{provide: 'PHOTO_REPOSITORY', // 自定义令牌useFactory: (dataSource: DataSource) => dataSource.getRepository(Photo),inject: ['DATA_SOURCE'],     // 声明依赖},
];

⚠️ 警告:在真实项目中,应避免使用“魔法字符串”(如 'PHOTO_REPOSITORY', 'DATA_SOURCE')。建议将它们定义在独立的 constants.tstokens.ts 文件中。

3. 在服务中注入仓储

现在可以在 PhotoService 中通过 @Inject() 装饰器注入 Photo 仓储。

// photo.service.ts
import { Injectable, Inject } from '@nestjs/common';
import { Repository } from 'typeorm';
import { Photo } from './photo.entity';@Injectable()
export class PhotoService {constructor(@Inject('PHOTO_REPOSITORY')private photoRepository: Repository<Photo>, // 注入仓储) {}async findAll(): Promise<Photo[]> {return this.photoRepository.find(); // 使用仓储查询所有照片}// 可以添加更多方法,如 create, update, delete 等
}

4. 创建 PhotoModule

最后,将所有部分组合成一个完整的模块。

// photo.module.ts
import { Module } from '@nestjs/common';
import { DatabaseModule } from '../database/database.module';
import { photoProviders } from './photo.providers';
import { PhotoService } from './photo.service';@Module({imports: [DatabaseModule], // 导入 DatabaseModule 以获取数据库连接providers: [...photoProviders,      // 注册 Photo 仓储提供者PhotoService,            // 注册服务],exports: [PhotoService],   // 如果其他模块需要使用此服务,需导出
})
export class PhotoModule {}

💡 提示:不要忘记将 PhotoModule 导入到根模块 AppModule 中。

总结与建议

  • 手动配置 vs 官方包:本文介绍的手动配置方式有助于深入理解 NestJS 的依赖注入机制和 TypeORM 的集成原理。
  • 推荐方案:在实际项目中,强烈建议使用 @nestjs/typeorm,它提供了更简洁、更安全的集成方式,减少了样板代码。
  • 生产环境:务必关闭 synchronize 选项,改用 TypeORM 的 Migration(迁移) 机制来管理数据库结构变更。
http://www.lryc.cn/news/623495.html

相关文章:

  • USB 2.0声卡
  • Python中f - 字符串(f-string)
  • 基于Vue的个人博客网站的设计与实现/基于node.js的博客系统的设计与实现#express框架、vscode
  • 进程互斥的硬件实现方法
  • 影刀初级B级考试大题2
  • 快速掌握Hardhat与Solidity智能合约开发
  • 模型提取的相关经验
  • JavaWeb前端(HTML,CSS具体案例)
  • C语言网络编程TCP通信实战:客户端↔服务器双向键盘互动全流程解析
  • Java线程的6种状态和JVM状态打印
  • Vue深入组件:Props 详解3
  • 2.Pod理论
  • Golang database/sql 包深度解析(二):连接池实现原理
  • 云原生俱乐部-RH134知识点总结(3)
  • PyCharm与前沿技术集成指南:AI开发、云原生与大数据实战
  • Spring Boot 项目配置 MySQL SSL 加密访问
  • Debug马拉松:崩溃Bug的终极挑战
  • 本地处理不上传!隐私安全的PDF转换解决方案
  • 华为云之Linux系统安装部署Tomcat服务器
  • Git 命令指南:从 0 到熟练、从常用到“几乎全集”(含常见报错与解决)建议收藏!!!
  • LintCode第137-克隆图
  • 学习游戏制作记录(玩家掉落系统,删除物品功能和独特物品)8.17
  • 《设计模式》工厂方法模式
  • 代码随想录算法训练营四十四天|图论part02
  • 天地图开发的优点
  • The Network Link Layer: 无线传感器中Delay Tolerant Networks – DTNs 延迟容忍网络
  • GANs生成对抗网络生成手写数字的Pytorch实现
  • VS Code配置MinGW64编译Apache Arrow C++库
  • 【k8s、docker】Headless Service(无头服务)
  • python+flask后端开发~项目实战 | 博客问答项目--模块化文件架构的基础搭建