NestJS中使用TypeORM(MongoDB)如何实现自定义Repository?
TypeORM 0.3+ 在NestJS中实现TypeScript友好的自定义仓库方案
@EntityRepository装饰器在TypeORM 0.3版本废弃后,不需要用任何第三方兼容包,直接基于NestJS原生依赖注入体系实现即可,全类型自动推导,同时兼容PostgreSQL、MongoDB等所有TypeORM支持的数据库,也不会出现0.2版本MongoDB下Repository not found的问题。
具体实现步骤
1. 编写自定义仓库类
不再需要继承TypeORM的Repository基类、也不需要加@EntityRepository装饰器,直接写标准的NestJS可注入类,在构造函数里注入对应实体的基础仓库实例即可:
// users.repository.ts import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { User } from './user.entity'; @Injectable() export class UsersRepository { constructor( @InjectRepository(User) private readonly baseRepo: Repository<User>, ) {} async createUser(firstName: string, lastName: string): Promise<User> { const user = this.baseRepo.create({ firstName, lastName }); await this.baseRepo.save(user); return user; } // 所有原生Repository的方法都可以通过this.baseRepo直接调用 // 比如按ID查询:async findById(id: number) { return this.baseRepo.findOneBy({ id }) } }
如果使用MongoDB,只需要把构造函数里的
Repository<User>替换为MongoRepository<User>即可,其余逻辑无需改动。
2. 服务层注入自定义仓库
服务层直接注入自定义仓库类即可,不需要额外传参给装饰器,所有方法的类型会自动推导,不会出现TS类型报错:
// users.service.ts import { Injectable } from '@nestjs/common'; import { User } from './user.entity'; import { UsersRepository } from './users.repository'; @Injectable() export class UsersService { constructor( private readonly usersRepository: UsersRepository, ) {} async createUser(firstName: string, lastName: string): Promise<User> { return this.usersRepository.createUser(firstName, lastName); } }
3. 调整模块注册配置
TypeOrmModule.forFeature中只需要注册实体本身,自定义仓库直接放到模块的providers数组中即可,不需要再传入forFeature:
// users.module.ts import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { UsersController } from './users.controller'; import { User } from './user.entity'; import { UsersRepository } from './users.repository'; import { UsersService } from './users.service'; @Module({ imports: [TypeOrmModule.forFeature([User])], controllers: [UsersController], providers: [UsersService, UsersRepository], exports: [UsersService], }) export class UsersModule {}
方案说明
- 这种写法完全遵循NestJS依赖注入设计规范,没有额外黑魔法,TypeScript类型覆盖率100%,调用自定义方法、原生仓库方法都不会有类型提示缺失的问题。
- 从根源上规避了0.2版本中MongoDB驱动无法识别通过
@EntityRepository注册的自定义仓库的问题,所有TypeORM支持的数据库写法完全统一。 - 如果需要使用事务、自定义操作等高级能力,直接在自定义仓库中注入
DataSource实例即可,和普通NestJS服务的写法完全一致。
内容的提问来源于stack exchange,提问作者unspeakable29
相关产品推荐
相关产品推荐

