typeORM 多对多关系不同情况的处理
本文以RBAC权限管理中的用户和角色举例,两个实体存在多对多的关系,一个用户拥有多个角色,一个角色属于多个用户。typeorm的中文文档没有对自定义中间表的说明,发现英文有相关说明,但示例代码貌似有问题。
一、中间表有自定义字段的处理
在用户user和role实体之外,新建一个roleUse的实体(记录用户和角色的关联关系),如此本来是多对多的关系,变成了user和role与roleUser二组一对多的关系,这样虽然会多定义一个实体,但好处是可以中间表可以扩展定义其它额外的数据
用户实体 user.entity.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 (主健)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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(复合主键)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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,此处主要讲双向
角色实体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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[]; } |
用户实体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 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[]; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步