如何创建如何在 typeorm 中创建多对多关系,[NestJS]

Posted

技术标签:

【中文标题】如何创建如何在 typeorm 中创建多对多关系,[NestJS]【英文标题】:how to create how to create many to many relationship in typeorm, [NestJS] 【发布时间】:2021-06-27 01:36:59 【问题描述】:

如何以多对多关系保存数据? (用户,书籍(MTM)) 这是用户和图书之间的多对多关系。 我的服务不正确。 另外,我的代码不起作用。 数据存储在 book 表中。

我需要你的帮助,一切 提前谢谢你。

我的堆栈 => NestJs、TypeORM、mysql

有我的实体。 enter image description here

用户.实体

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

    @Column()
    real_name!: string;

    @Column()
    nick_name!: string;

    @Column()
    @IsEmail()
    email!: string;

    @Column()
    password!: string;

    @Column()
    phone_number!: string;

    @Column()
    image_url: string;

    @BeforeInsert()
    async hashPassword() 
        this.password = await argon2.hash(this.password, type: argon2.argon2id, hashLength: 40);
    

book.entity

@Entity('Book')
export class Book 
    @PrimaryGeneratedColumn()
    id!: number;

    @Column()
    title: string;

    @Column()
    image_url: string;

    @Column()
    contents: string;

    @Column( type: 'datetime')
    datetime: string;

    @ManyToMany(() => User)
    @JoinTable()
    users: User[];

book.controller.ts

@UseGuards(JwtAuthGuard)
    @Post('bpc')
    savebpc(@Req() req: any, @Query('title') bookTitle: string)
        return this.BookService.addBpc(req, bookTitle);
    

book.service.ts

async addBpc(req: any, bookTitle: string): Promise<any>
        const userId = req.user.id;
        const bookId = await getRepository('Book')
        .createQueryBuilder('book')
        .where(title:bookTitle)
        .getRawOne()

        if (!bookId)
            throw new NotFoundException('Not_found_book');
        

        const user = await getRepository('User')
        .createQueryBuilder('user')
        .where(id: userId)
        .getRawOne()


        //bookId.user.push(user);
        //await this.bookRepository.save(bookId);

        let userdata = new User();
        userdata.id = user.user_id;
        userdata.real_name = user.user_real_name;
        userdata.nick_name = user.user_nick_name;
        userdata.email = user.user_email;
        userdata.password = user.user_password;
        userdata.image_url = user.user_image_url;
        console.log(userdata);
        

        let bookBpc = new Book();
        bookBpc.title = bookId.book_title;
        bookBpc.image_url = bookId.book_image_url;
        bookBpc.contents = bookId.book_contents;
        bookBpc.datetime = bookId.book_datetime;
        bookBpc.users = [user];
        console.log(bookBpc);

        await this.bookRepository.create([bookBpc]);
        return 'suceess';
    

【问题讨论】:

【参考方案1】:

你需要在 user 和 book 中添加 manytomany 关系,这里是一个使用 express 和 typeorm 的例子,但它与 nestjs 相同

用户实体:

@Entity()
export class User 
  @PrimaryGeneratedColumn()
  id: number;
  @Column( type: 'varchar', nullable: false, unique: true )
  username: string;
  // we need to add a default password and get it form the .env file
  @Column( type: 'varchar', nullable: true, default: '' )
  password: string;
  @Column( type: 'varchar', nullable: true )
  firstname: string;
  @Column( type: 'varchar', nullable: true )
  lastname: string;
  @Column( type: 'varchar', nullable: false )
  email: string;
  @Column( type: 'boolean', nullable: true, default: false )
  connected: boolean;
  @CreateDateColumn( name: 'created_at' )
  createdAt: Date;

  @UpdateDateColumn( name: 'updated_at' )
  updatedAt: Date;

  // new properties
  @Column( name: 'login_attempts', type: 'int', default: 0, nullable: true )
  loginAttempts: number;
  @Column( name: 'lock_until', type: 'bigint', default: 0, nullable: true )
  lockUntil: number;

  //Many-to-many relation with role
  @ManyToMany((type) => Role, 
    cascade: true,
  )
  @JoinTable(
    name: "users_roles",
    joinColumn:  name: "userId", referencedColumnName: "id" ,
    inverseJoinColumn:  name: "roleId" 
  )
  roles: Role[];

角色实体:

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

  @Column( type: 'varchar', nullable: false, unique: true )
  profile: string;

  @Column( type: 'varchar', nullable: false )
  description: string;

  //Many-to-many relation with user
  @ManyToMany((type) => User, (user) => user.roles)
  users: User[];
  @CreateDateColumn( name: 'created_at' )
  createdAt: Date;

  @UpdateDateColumn( name: 'updated_at' )
  updatedAt: Date;

这是在 user_role 中保存数据的方法:

let entity = await this.userRepository.create(data); //here you create new dataobject that contain user columns 

  let entity2 =  ...entity, roles: data.selectedRoles  // you have to add the association roles here 

  const user = await this.userRepository.save(entity2); 

【讨论】:

非常感谢您在忙碌中的回答。我从答案中得到了提示,并用下面的代码解决了它虽然看起来像一个快捷方式,但没关系。 await getConnection() .createQueryBuilder() .relation(Book, "users") .of(bookBpc) .add(userdata);

以上是关于如何创建如何在 typeorm 中创建多对多关系,[NestJS]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 schema.graphql 在放大数据存储中创建多对多关系

如何在实体框架中创建多对多映射?

在控制器中创建多对多模型的模式

使用嵌套字段在MongoDB / Mongoose中创建多对多关系?

如何在rails的同一个表中创建多对多

使用flask-restplus在flask-SQLAlchemy中创建多对多关联表时出错