Nestjs使用sequelize完成多表操作(一对多、多对多)
书接上回,上次的文章介绍了nestjs中sequelize操作单表(User表)。这次继续介绍多表操作。Role表与User表存在多对多关系(每个用户可以有多个角色,每个角色包含多个用户)。License(车牌)表与User表存在一对多关系(每辆车只能有一个户主,每个户主可以有多辆车)。
关于创建实例对象、关联数据表、nestjs引入sequelize等可以参考本专栏第一篇文章。本篇主要说明多表操作。 # Nestjs使用sequelize完成单表操作
前置说明。先看一下ER图直观的看一下四个表之间的关系
先处理一对多关联.建立License表
// licenses/license.model.ts
import { Column, Table, Model, ForeignKey, BelongsTo } from 'sequelize-typescript';
import { User } from '../users/user.model';
@Table({
tableName: 'user_license',
timestamps: false,
})
export class License extends Model<License> {
@Column
license_num: string;
@ForeignKey(() => User) // 定义user_id字段为外键,关联User表
@Column
user_id: number;
@BelongsTo(() => User) // 定义多对一关系。注意使用BelongsTo是多对一关系的【多】表
user: User;
}
再处理多对多关联。多对多关系需要一张中间关联表。所以我们先建立一张RoleUser表。在表中声明外键。将User和Role关联。(注意在Role/User与RoleUser的关系是一对多。User与Role的关系才是多对多)
// role_users/role_user.model.ts
import { Column, Table, Model, BelongsTo, ForeignKey } from 'sequelize-typescript';
import { Role } from '../roles/role.model'; // 引入User表,
import { User } from '../users/user.model'; // 引入User表,注意:Role表等下再建立哈
@Table({
tableName: 'admin_role_user', // 数据库中有改该表
timestamps: false,
})
export class RoleUser extends Model<RoleUser> {
@ForeignKey(() => User)
@Column
user_id: number; // 外键user_id关联到User表中的主键id
@BelongsTo(() => User) // 同理定义多对一关系。注意使用BelongsTo是多对一关系的【多】表
user: User[];
@ForeignKey(() => Role)
@Column
role_id: number;// 外键role_id关联到User表中的主键id
@BelongsTo(() => Role)
role: Role[];
}
再定义Role实例(Role表并不需要再和RoleUser关联。只需和User关联。同理User也只需要和Role关联)
// roles/role.model.ts
import { Column, Table, Model, BelongsToMany } from 'sequelize-typescript';
import { RoleUser } from '../role_users/role_user.model';
import { User } from '../users/user.model';
@Table({
tableName: 'admin_role',
timestamps: false,
})
export class Role extends Model<Role> {
@Column
name: string;
@Column
remarks: string;
@BelongsToMany(() => User, () => RoleUser) // 建立多对多关联。第二个参数是中间表UserRole
users: User[];
}
大家也能想到User表中的结构了
import { Column, Table, Model, HasMany, BelongsToMany } from 'sequelize-typescript';
import { License } from '../licenses/license.model';
import { RoleUser } from '../role_users/role_user.model';
import { Role } from '../roles/role.model';
@Table({
tableName: 'admin_user',
timestamps: false,
})
export class User extends Model<User> {
@Column
username: string;
@Column
password: string;
@Column
email: string;
@Column
mobile: string;
@Column
create_time: Date;
@HasMany(() => License) // 一对多关系中的【一】表使用的hasmany。很语义化
licenses: License[];
@BelongsToMany(() => Role, () => RoleUser)
roles: Role[];
}
下面再看一下users.service.ts中如何使用User实例
// users.service.ts
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { User } from './user.model';
import { License } from '../licenses/license.model';
import { Role } from '../roles/role.model';
import { RoleUser } from '../role_users/role_user.model';
@Injectable()
export class UsersService {
constructor(
@InjectModel(User)
private userModel: typeof User
) {}
findAll(): Promise<User[]> {
return this.userModel.findAll({
attributes: ['username'], // 指定查找User表中的部分字段
include: [
{
model: Role, // 查表时包括Role表和License表。并且制定查出具体的字段。实例的具体方法可到官网学习
attributes: ['remarks', 'name'],
},
{
model: License,
attributes: ['license_num'],
},
],
});
}
}
Postman查表验证
到此为止多表联查的操作就完成了。如果需要在多表中进行删除或者插入、更新操作还没有一次性完成的解决方案。希望大家不吝赐教。 NPM的sequelize-typescript英文文档
转载自:https://juejin.cn/post/7047456336031776776