在 Nest JS / TypeORM 中使用具有关系的实体内部的实体并填充数据库

Posted

技术标签:

【中文标题】在 Nest JS / TypeORM 中使用具有关系的实体内部的实体并填充数据库【英文标题】:Using entity inside entity with relationships and populating database in Nest JS / TypeORM 【发布时间】:2022-01-12 18:44:42 【问题描述】:

假设我们正在为一个新的 Web 应用程序构建我们的第一个实体。 有一个用户实体

@Entity()
export class User 
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  username: string;

  @Column()
  password: string;

  @OneToOne(() => Author)
  author: Author;

用户注册后可以成为作者。所以用户和作者表之间存在一对一的关系。假设我们有另一个 名为 books 的表,一个作者可以有 多个 书。

export class Author 
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  Name: string;

  @OneToMany(() => Book, (Book) => Book.Author)
  Book: Book[];

  @OneToOne(() => User)
  @JoinColumn()
  User: User;

这是图书存储库的示例实体:

export class Book 
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  Name: string;

  @Column()
  ISIN: string;

  @OneToOne(() => Author)
  @JoinColumn()
  Author: Author;

问题是,当我们迁移这些实体并构建我们的第一个/干净的数据库时,我们如何通过调用 API 插入数据? API Post 方法的示例服务:

@Injectable()
export class BookService 
  constructor(
    @InjectRepository(Book)
    private BookRepository: Repository<Book>,
  ) 
  async create(createBookDto: CreateBookDto) 
    await this.BookRepository.insert(createBookDto);
  

和控制器:

@Controller('books')
export class BookController 
  constructor(private readonly BookService: BookService) 

  @Post('/Book')
  create(@Body() createBookDto: CreateBookDto) 
    return this.BookService.create(createBookDto);
  

这里的问题是,当我想通过 POST 数据到 API 路由来创建一本新书时,它需要定义作者。那么如何通过此服务将现有用户书籍作者数据 发布到数据库中? 我认为最好的选择是创建一个 类的新实例,从 request @Body 获取数据并将其分配给类的对象,然后将其保存到数据库。 但我认为这不是一个好的解决方案,因为它更倾向于使用存储库而不是对象类类型。

【问题讨论】:

【参考方案1】:

我认为您在实体定义中犯了一个错误。 Author 与 Book 之间存在 OneToMany 关系。

像这样修改您的图书实体

export class Book 
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  Name: string;

  @Column()
  ISIN: string;

  @ManyToOne(() => Author, author=> author.book,  nullable: true )
  @JoinColumn()
  Author: Author;

nullable: true 这将允许您在没有作者的情况下保存您的图书数据。

修改您的服务以保存图书信息

public async create(createBookDTO: CreateBookDTO) 
        try 
            if (
                createBookDTO.hasOwnProperty('author') &&
                createTaskDTO.author
            ) 
                const author = await this.connection.manager.findOne(Author, 
                    where: 
                        id: createBookDTO.author,
                    ,
                );
                if (author) 
                    createBookDTO.author = author;
                 else 
                    throw new NotAcceptableException('Author not found');
                
            

            return await this.bookRepo.save(createBookDTO);
         catch (err) 
            throw new HttpException(err, err.status || HttpStatus.BAD_REQUEST);
        
    

【讨论】:

以上是关于在 Nest JS / TypeORM 中使用具有关系的实体内部的实体并填充数据库的主要内容,如果未能解决你的问题,请参考以下文章

nest.js + typeORM:基本使用

无法连接到数据库 - NEST.JS 和 TypeORM

如何在 typeorm 和 nest.js 中设置布尔验证

nest.js + typeORM:身份认证,事务管理

Nest.js TypeORM 连接到本地数据库(在 docker 容器上)

Nest js 和 typeorm 自定义存储库问题