typescript 如何在NestJS中使用TypeORM(MongoDB)进行自定义仓库?

zc0qhyus  于 2023-06-07  发布在  TypeScript
关注(0)|答案(4)|浏览(200)

我有个问题随着@EntityRepository decorator在typeorm@^0.3.6中被标记为已弃用,现在推荐的或TypeScript友好的方法是什么?以前的自定义存储库看起来像这样:

// users.repository.ts
import { EntityRepository, Repository } from 'typeorm';
import { User } from './user.entity';

@EntityRepository(User)
export class UsersRepository extends Repository<User> {
  async createUser(firstName: string, lastName: string): Promise<User> {
    const user = this.create({
      firstName,
      lastName,
    });

    await this.save(user);

    return user;
  }
}

由于NestJS默认配置了TypeScript支持,我将能够在这样的服务中调用usersRepository.createUser()而不会出现问题:

// users.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UsersRepository } from './users.repository';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(UsersRepository)
    private readonly usersRepository: UsersRepository,
  ) {}

  async createUser(firstName: string, lastName: string): Promise<User> {
    return this.usersRepository.createUser(firstName, lastName);
  }
}

下面是模块导入自定义存储库的方式:

// users.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersController } from './users.controller';
import { UsersRepository } from './users.repository';
import { UsersService } from './users.service';

@Module({
  imports: [TypeOrmModule.forFeature([UsersRepository])],
  controllers: [UsersController],
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}

另外,我在这里提到MongoDB的原因是因为我尝试使用typeorm@0.2,其中仍然支持@EntityRepository,但当我试图将其导入到模块中时收到错误,说明Repository not found或其他内容。请注意,如果我在TypeORM中选择postgresql作为我的数据库,并进行了上述相同的更改,则不会出现此问题。因此,我去检查最新的,只发现它已经被弃用,我也没有找到任何例子在NestJS文档。

cx6n0qe3

cx6n0qe31#

我想我找到了一个解决方案,它允许调用自定义方法,但也允许调用继承的方法。这个“问题”似乎还不太流行,但在typeorm GitHub线程中肯定有一些关于它的讨论:https://github.com/typeorm/typeorm/issues/9013
下面的解决方案使用MySQL作为底层数据库驱动程序,但我认为它也适用于MongoDB。

team.repository.ts

import {DataSource, Repository} from 'typeorm';
import {Injectable} from '@nestjs/common';
import {Team} from '@Domain/Team/Models/team.entity';

@Injectable()
export class TeamRepository extends Repository<Team>
{
    constructor(private dataSource: DataSource)
    {
        super(Team, dataSource.createEntityManager());
    }

    /**
     * Add a basic where clause to the query and return the first result.
     */
    async firstWhere(column: string, value: string | number, operator = '='): Promise<Team | undefined>
    {
        return await this.createQueryBuilder()
                         .where(`Team.${column} ${operator} :value`, {value: value})
                         .getOne();
    }
}

team.service.ts

import {Injectable} from '@nestjs/common';
import {Team} from '@Domain/Team/Models/team.entity';
import {TeamRepository} from '@Domain/Team/Repositories/team.repository';

@Injectable()
export class TeamService
{
    constructor(
        private teamRepository: TeamRepository,
    )
    {
    }

    async create(): Promise<Team>
    {
        const team: Team = await this.teamRepository.firstWhere('id', 1);

        return this.teamRepository.save(team);
    }
}

team.module.ts

import {Module} from '@nestjs/common';
import {TeamService} from '@Domain/Team/Services/team.service';
import {TypeOrmModule} from '@nestjs/typeorm';
import {Team} from '@Domain/Team/Models/team.entity';
import {TeamRepository} from '@Domain/Team/Repositories/team.repository';

@Module({
            imports:   [TypeOrmModule.forFeature([Team])],
            exports:   [TeamService],
            providers: [TeamService, TeamRepository],
        })
export class TeamModule
{
}
8dtrkrch

8dtrkrch2#

TypeORM中为mongo创建自定义仓库的方法如下:

users.repository.ts

在这里,您将使用@Injectable装饰器而不是@EntityRepository,对于inject,schema将使用MongoRepository

// users.repository.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { MongoRepository } from 'typeorm';
import { User } from './user.entity';
@Injectable()
export class UsersRepository {
  constructor(
    @InjectRepository(User)
    private readonly usersRepository: MongoRepository<User>,
  ) {}

  async createUser(firstName: string, lastName: string): Promise<User> {
    const user = new User({
      firstName,
      lastName,
    });

    await this.usersRepository.save(user);

    return user;
  }
  

   //write other helpful methods here(find, delete, etc...)

}

users.service.ts

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
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);
  }
}

users.module.ts

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersController } from './users.controller';
import { UsersRepository } from './users.repository';
import { UsersService } from './users.service';
import { User } from './user.entity';
import { UsersRepository } from './database/repository/UsersRepository';
@Module({
  imports: [TypeOrmModule.forFeature([User])],
  controllers: [UsersController],
  providers: [UsersRepository, UsersService],
  exports: [UsersService],
})
export class UsersModule {}
00jrzges

00jrzges3#

// task.entity.ts
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Task {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  title: string;

  @Column()
  description: string;
}
// tasks.repository.ts
import { Injectable } from '@nestjs/common';
import { DataSource, Repository } from 'typeorm';
import { Task } from './tast.entity';

@Injectable()
export class TasksRepository extends Repository<Task> {
  constructor(dataSource: DataSource) {
    super(Task, dataSource.createEntityManager());
  }
}
//tasks.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TasksController } from './tasks.controller';
import { TasksService } from './tasks.service';
import { Task } from './tast.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Task])], // NOTICE: HERE
  controllers: [TasksController], // NOTICE: HERE
  providers: [TasksService],
})
export class TasksModule {}
@Injectable()
export class TasksService {
  constructor(
    @InjectRepository(Task) // NOTICE: here
    private readonly tasksRepository: TasksRepository,
  ) {}

  async getTaskById(id: string): Promise<Task> {
    const task = this.tasksRepository.findOne({
      where: {
        id,
      },
    });

    if (!task) {
      throw new NotFoundException(`Task with id ${id} not found`);
    }

    return task;
  }
}
vmjh9lq9

vmjh9lq94#

我刚刚开发了一个解决这个问题的软件包,你可以看看。
nestjs-typeorm-custom-repository

// users.repository.ts
import { Repository } from 'typeorm';
import { EntityRepository } from 'nestjs-typeorm-custom-repository';

import { User } from './user.entity';

@EntityRepository(User)
export class UsersRepository extends Repository<User> {}
// users.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UsersRepository } from './users.repository';

@Injectable()
export class UsersService {
  constructor(
    private readonly usersRepository: UsersRepository,
  ) {}
  ...
  }
}
// users.module.ts
import { Module } from '@nestjs/common';
import { CustomRepositoryModule } from 'nestjs-typeorm-custom-repository';

import { UsersController } from './users.controller';
import { UsersRepository } from './users.repository';
import { UsersService } from './users.service';

@Module({
  imports: [CustomRepositoryModule.forFeature([UsersRepository])],
  controllers: [UsersController],
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}

相关问题