如何使用 TypeORM 0.3.x 在 NestJS 9 中创建自定义(单独文件)存储库

APu*_*APu 8 repository-pattern typeorm nestjs

这不是重复的问题。请不要将其标记为那样。

以下不是我想要的

import { EntityRepository, Repository } from "typeorm";
import { Test } from "./test.model";
import { Injectable } from "@nestjs/common";

@EntityRepository(Test)
export class TestRepository extends Repository<Test> {}
Run Code Online (Sandbox Code Playgroud)

装饰@EntityRepository器现在已被弃用。

我也不想像这里一样创建一个假存储库: /sf/answers/5134658581/

我也不想要这个,因为我必须从中提取managerdataSource我不想要这个,因为我认为这不是最好的方法。

    export const UserRepository = dataSource.getRepository(User).extend({
        //                        ^^^^^^^^^^ from where this came from
        findByName(firstName: string, lastName: string) {
            return this.createQueryBuilder("user")
                .where("user.firstName = :firstName", { firstName })
                .andWhere("user.lastName = :lastName", { lastName })
                .getMany()
        },
    })
Run Code Online (Sandbox Code Playgroud)

上面找到: https: //orkhan.gitbook.io/typeorm/docs/custom-repository#how-to-create-custom-repository

我不认为这是在 NestJS 上下文中。

我想要什么想知道在最新版本的 NestJS (v9) 和 TypeORM (v0.3) 中创建自定义存储库的正确方法。在@EntityRepository弃用说明中,他们说需要扩展存储库以创建自定义存储库,例如someRepo.extend({}). 我想知道如何以 NestJS 的方式做到这一点

A. *_*tre 12

为了实现您想要的目标,您可以执行以下操作。

该解决方案的灵感来自与该主题相关的官方 NestJS 文档,并进行了一些定制。

实现它的步骤:

  1. 像往常一样创建TypeOrmUserEntity实体(user.entity.ts文件)
  2. 创建一个UserRepository类(user.repository.ts文件)
  3. 像往常一样创建一个UserService类(user.service.ts文件)
  4. 将其导入UserRepository到您的UserService
  5. 更新UserModule以提供UserRepository所需的UserEntity

详细实现示例

1.user.entity.ts文件

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class UserEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;
}
Run Code Online (Sandbox Code Playgroud)

2.user.repository.ts文件

import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { UserEntity } from './user.entity';

export class UserRepository extends Repository<UserEntity> {
    constructor(
        @InjectRepository(UserEntity)
        private userRepository: Repository<UserEntity>
    ) {
        super(userRepository.target, userRepository.manager, userRepository.queryRunner);
    }

    // sample method for demo purposes
    async findByEmail(email: string): Promise<UserEntity> {
        return await this.userRepository.findOneBy({ email }); // could also be this.findOneBy({ email });, but depending on your IDE/TS settings, could warn that userRepository is not used though. Up to you to use either of the 2 methods
    }
    
    // your other custom methods in your repo...
}
Run Code Online (Sandbox Code Playgroud)

3.& 4.user.service.ts文件

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

@Injectable()
export class UserService {
  constructor(
    private readonly userRepository: UserRepository, // import as usual
  ) {}

  findAll(): Promise<UserEntity[]> {
    return this.userRepository.find();
  }
  
  // call your repo method
  findOneByEmail(email: string): Promise<UserEntity> {
    return this.userRepository.findByEmail({ email });
  }

  findOne(id: number): Promise<UserEntity> {
    return this.userRepository.findOneBy({ id });
  }

  async remove(id: string): Promise<void> {
    await this.userRepository.delete(id);
  }
  
  // your other custom methods in your service...
}
Run Code Online (Sandbox Code Playgroud)

5.更新UserModuleuser.module.ts文件)

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { UserEntity } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([UserEntity])], // here we provide the TypeOrm support as usual, specifically for our UserEntity in this case
  providers: [UserService, UserRepository], // here we provide our custom repo
  controllers: [UserController],
  exports: [UserService, UserRepository] // add this only if you use service and/or custom repo within another module/service
})
export class UserModule {}
Run Code Online (Sandbox Code Playgroud)

完成此操作后,您应该能够UserModule在 中导入AppModule,并且能够在 中实现自定义方法UserRepository并在UserService. 您还应该能够调用自定义存储库的manager和。queryRunnner

附加说明

如果您需要直接UserRepository从另一个模块/服务中调用您的方法,请更新UserModule以导出UserRepository

希望对您有所帮助,请不要犹豫发表评论。