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

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.xdnf.cn/news/18222.html

相关文章:

  • 关于第一次接触Linux TCP/IP网络相关项目
  • Docker入门:容器化技术的第一堂课
  • python---装饰器
  • 在线编程题目之小试牛刀
  • [每周一更]-(第155期):Go 1.25 发布:新特性、技术思考与 Go vs Rust 竞争格局分析
  • 回溯剪枝的 “减法艺术”:化解超时危机的 “救命稻草”(一)
  • 机器学习算法篇(十三)------词向量转化的算法思想详解与基于词向量转换的文本数据处理的好评差评分类实战(NPL基础实战)
  • 微服务之间的调用需要走网关么?
  • Linux Shell定时检查日期执行Python脚本
  • Python数据类型转换详解:从基础到实践
  • uniappx 安卓端本地打包的一些总结
  • 【typenum】 16 非零标记及改进建议
  • 【Linux系统】动静态库的制作
  • java之 junit4单元测试Mockito的使用
  • Pycharm Debug详解
  • 深度学习之优化器
  • 数据与模型融合波士顿房价回归建模预测
  • 数据结构(排序篇)——七大排序算法奇幻之旅:从扑克牌到百亿数据的魔法整理术
  • LeetCode 1323: 6和9组成的最大数字
  • 内网后渗透攻击--隐藏通信隧道技术(应用层隧道技术)
  • 一键管理 StarRocks:简化集群的启动、停止与状态查看
  • JAVA后端开发——Token自动续期机制的必要性
  • 库制作与原理(下)
  • RabbitMQ面试精讲 Day 24:消费者限流与批量处理
  • Linux中iSCSI存储配置与管理指南
  • Leetcode 15 java
  • 【LeetCode 热题 100】118. 杨辉三角
  • 使用Github Page发布网站
  • Compose笔记(四十六)--Popup
  • 廖雪峰-java教程-Part01