简体   繁体   English

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

[英]How to do custom repository using TypeORM (MongoDB) in NestJS?

I have a question.我有个问题。 With @EntityRepository decorator being marked as deprecated in typeorm@^0.3.6 , what is now the recommended or TypeScript-friendly way to create a custom repository for an entity in NestJS?随着@EntityRepository装饰器在 typeorm@^0.3.6 中被标记为已弃用,现在在typeorm@^0.3.6中为实体创建自定义存储库的推荐或 TypeScript 友好方式是什么? A custom repository before would look like this:之前的自定义存储库如下所示:

// 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;
  }
}

And since NestJS is by default configured with TypeScript support, I will be able to call usersRepository.createUser() without an issue in a service like this:而且由于 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);
  }
}

This is how the modules would import the custom repository:这是模块导入自定义存储库的方式:

// 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 {}

Also the reason why I mentioned MongoDB here is because I tried using typeorm@0.2 where @EntityRepository is still supported but I receive an error when I tried to import it in the module stating Repository not found or something.另外,我在这里提到 MongoDB 的原因是因为我尝试使用仍然支持typeorm@0.2@EntityRepository ,但是当我尝试在模块中导入它时收到错误,说明Repository not found或其他内容。 Do note, if I chose postgresql as my database in TypeORM with the same changes above, I don't have this issue.请注意,如果我在 TypeORM 中选择postgresql作为我的数据库并进行上述相同的更改,我就没有这个问题。 Hence I went to check the latest only to find out it is already deprecated, I also didn't find any example in NestJS documentation.因此我去检查最新的只是发现它已经被弃用了,我也没有在 NestJS 文档中找到任何示例。

I think I found a solution to this which allows to call custom methods but also inherited ones.我想我找到了一个解决方案,它允许调用自定义方法,也可以调用继承的方法。 It seems that this "issue" is not too popular yet but there is definitely some chatter about it within the typeorm GitHub threads: https://github.com/typeorm/typeorm/issues/9013似乎这个“问题”还不太流行,但在 typeorm GitHub 线程中肯定有一些关于它的讨论: https ://github.com/typeorm/typeorm/issues/9013

The following solution uses MySQL as underlying database driver but I assume it will work for MongoDB as well.以下解决方案使用 MySQL 作为底层数据库驱动程序,但我认为它也适用于 MongoDB。

team.repository.ts 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团队服务.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团队模块.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
{
}

The way you can create a custom repository for mongo in TypeORM it with the following way:您可以通过以下方式在TypeORM中为 mongo 创建自定义存储库:

users.repository.ts users.repository.ts

Here instead of using @EntityRepository you will use the @Injectable decorator, and for inject, the schema will use MongoRepository在这里,您将使用@Injectable装饰器而不是使用@EntityRepository ,对于注入, 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;
  }
}

users.service.ts 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 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 {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM