typeORM 多对多关系不同情况的处理

Posted terrylin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了typeORM 多对多关系不同情况的处理相关的知识,希望对你有一定的参考价值。

本文以RBAC权限管理中的用户和角色举例,两个实体存在多对多的关系,一个用户拥有多个角色,一个角色属于多个用户。typeorm的中文文档没有对自定义中间表的说明,发现英文有相关说明,但示例代码貌似有问题。

 

一、中间表有自定义字段的处理

在用户user和role实体之外,新建一个roleUse的实体(记录用户和角色的关联关系),如此本来是多对多的关系,变成了user和role与roleUser二组一对多的关系,这样虽然会多定义一个实体,但好处是可以中间表可以扩展定义其它额外的数据

 

用户实体 user.entity.ts

import  Entity, Column, Index, ManyToMany, JoinColumn, OneToMany, JoinTable, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn  from ‘typeorm‘;
import  Role  from ‘../../admin/role/role.entity‘;
import  UserRole  from ‘../../admin/role/roleUser.entity‘;

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

    @Column( length: 100 )
    @Index( unique: true )
    name: string;

    @OneToMany(type => UserRole, userRole => userRole.user)
    userRoles: UserRole[];

 

角色实体role.entity.ts

import  Entity, Column, ManyToMany, OneToMany, JoinTable, JoinColumn  from ‘typeorm‘;
import  BaseEntity  from ‘../../../common/base/base.entity‘;
import  UserRole  from ‘./roleUser.entity‘;

@Entity(‘role‘)
export class Role extends BaseEntity 
    @Column( length: 100 )
    role_name: string;

    @OneToMany(type => UserRole, userRole => userRole.role)
    userRoles: UserRole[];

 

中间表实体 roleUser.entity.ts (主健)

import  Entity, PrimaryGeneratedColumn, JoinColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne  from ‘typeorm‘;
import  BaseEntity  from ‘../../../common/base/base.entity‘;
import  User  from ‘../../web/user/user.entity‘;
import  Role  from ‘./role.entity‘;

@Entity()
export class UserRole 
    @PrimaryGeneratedColumn()
    public id: number;

    @CreateDateColumn()
    created_time: Date;

    @UpdateDateColumn()
    updated_time: Date;

    @ManyToOne(type => User, user => user.userRoles)
    @JoinColumn(name: ‘user_id‘)
    user: User;

    @ManyToOne(type => Role, role => role.userRoles)
    @JoinColumn(name: ‘role_id‘)
    role: Role;

 

中间表定义roleUser.entity.ts(复合主键)

import  Entity, PrimaryGeneratedColumn, JoinColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne  from ‘typeorm‘;
import  BaseEntity  from ‘../../../common/base/base.entity‘;
import  User  from ‘../../web/user/user.entity‘;
import  Role  from ‘./role.entity‘;

@Entity()
export class UserRole 

    @CreateDateColumn()
    created_time: Date;

    @UpdateDateColumn()
    updated_time: Date;

    @ManyToOne(type => User, user => user.userRoles,  primary: true )
    @JoinColumn(name: ‘user_id‘)
    user: User;

    @ManyToOne(type => Role, role => role.userRoles,  primary: true )
    @JoinColumn(name: ‘role_id‘)
    role: Role;

  

二、无中间表的多对多实体定义,又分为单向和双向,单向是仅在一侧与关系装饰器的关系, 双向是与关系两侧的装饰者的关系。具体官网文档:https://typeorm.io/#/relations,此处主要讲双向

 

角色实体  

import  Entity, Column, ManyToMany, OneToMany, JoinTable, JoinColumn  from ‘typeorm‘;
import  BaseEntity  from ‘../../../common/base/base.entity‘;
import  User  from ‘../../web/user/user.entity‘;

@Entity(‘role‘)
export class Role extends BaseEntity 
    @Column( length: 100 )
    role_name: string;

    @Column( length: 100 )
    remark: string;

    // 无中间实体表的配置
    @ManyToMany(type => User, user => user.roles,  cascade: true )
    users: User[];


 

用户实体

import  Entity, Column, Index, ManyToMany, JoinColumn, OneToMany, JoinTable, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn  from ‘typeorm‘;
import  Role  from ‘../../admin/role/role.entity‘;

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

    @Column( length: 100 )
    @Index( unique: true )
    name: string;

    // 无中间实体表的配置
    @ManyToMany(type => Role, role => role.users)
    @JoinTable(
        name: ‘user_role‘,
        joinColumns: [
            name: ‘user_id‘
        ],
        inverseJoinColumns: [
            name: ‘role_id‘
        ]
    )
    // 下面的定义也能实现
    //   @JoinTable(
    //     name: ‘user_role‘,
    //     joinColumn:  name: ‘user_id‘ ,
    //     inverseJoinColumn:  name: ‘role_id‘ ,
    //   )
    roles: Role[];


  

  

以上是关于typeORM 多对多关系不同情况的处理的主要内容,如果未能解决你的问题,请参考以下文章

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

TypeORM:使用自定义属性查询多对多

TypeORM:如何查询与字符串数组输入的多对多关系以查找所有字符串都应存在于相关实体列中的实体?

自引用多对多关系类型ORM

为两个实体设置多对多关系装饰器与创建第三个实体?

与 SQLAlchemy 中不同的其他对象、自身和属性的多对多关系