You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NestJS v8中实现自定义通用Repository(TypeORM v8.1.2)

实现NestJS v8 + TypeORM v8.1.2的通用自定义仓库

TypeORM v8.x 已经废弃了@EntityRepository装饰器,我们可以通过继承Repository并结合NestJS的依赖注入来实现通用自定义仓库,具体步骤如下:

1. 创建通用基础仓库类

先封装一个包含通用方法的基础仓库,所有实体仓库都将继承这个类,实现逻辑复用:

import { Repository, EntityManager, FindManyOptions } from 'typeorm';

export class BaseRepository<T> extends Repository<T> {
  constructor(entityManager: EntityManager, entity: new () => T) {
    super(entity, entityManager);
  }

  // 通用分页查询方法
  async findPaginated(page: number = 1, limit: number = 10, options?: FindManyOptions<T>): Promise<[T[], number]> {
    return this.findAndCount({
      skip: (page - 1) * limit,
      take: limit,
      ...options,
    });
  }

  // 通用软删除方法(需实体包含deletedAt字段)
  async softDeleteByConditions(conditions: Partial<T>): Promise<void> {
    await this.update(conditions, { deletedAt: new Date() } as Partial<T>);
  }
}

2. 为具体实体创建自定义仓库

针对每个业务实体,创建继承自BaseRepository的专属仓库,添加实体特有的自定义方法:

import { Injectable } from '@nestjs/common';
import { InjectEntityManager } from '@nestjs/typeorm';
import { EntityManager } from 'typeorm';
import { BaseRepository } from './base.repository';
import { User } from './user.entity';

@Injectable()
export class UserRepository extends BaseRepository<User> {
  constructor(@InjectEntityManager() entityManager: EntityManager) {
    super(entityManager, User);
  }

  // 实体专属方法:查询活跃用户
  async findActiveUsers(): Promise<User[]> {
    return this.createQueryBuilder('user')
      .where('user.isActive = :isActive', { isActive: true })
      .orderBy('user.createdAt', 'DESC')
      .getMany();
  }

  // 实体专属方法:根据用户名模糊查询
  async findByUsernameLike(username: string): Promise<User[]> {
    return this.createQueryBuilder('user')
      .where('user.username LIKE :username', { username: `%${username}%` })
      .getMany();
  }
}

3. 在NestJS模块中注册仓库

将自定义仓库加入模块的providers数组,确保能被依赖注入:

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UserRepository } from './user.repository';
import { UserService } from './user.service';

@Module({
  imports: [TypeOrmModule.forFeature([User])], // 注册实体到TypeORM模块
  providers: [UserRepository, UserService],
  exports: [UserRepository], // 如需跨模块使用,导出仓库
})
export class UserModule {}

4. 在Service中注入使用

在业务Service中直接注入自定义仓库,调用通用或专属方法:

import { Injectable } from '@nestjs/common';
import { UserRepository } from './user.repository';
import { User } from './user.entity';

@Injectable()
export class UserService {
  constructor(private readonly userRepository: UserRepository) {}

  async getActiveUsers(): Promise<User[]> {
    return this.userRepository.findActiveUsers();
  }

  async getUsersPage(page: number, limit: number): Promise<[User[], number]> {
    return this.userRepository.findPaginated(page, limit);
  }

  async searchUsersByUsername(username: string): Promise<User[]> {
    return this.userRepository.findByUsernameLike(username);
  }
}

关键说明

  • 通过@InjectEntityManager获取EntityManager,传入基础仓库的构造函数,实现对实体的操作能力
  • 通用仓库BaseRepository可封装所有实体共用的逻辑,避免重复代码
  • 每个实体仓库只需专注实现自身业务相关的自定义方法,保持代码职责清晰

内容的提问来源于stack exchange,提问作者soroush

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 21:27:28