多对多
在如今的社会,我们非常喜欢给人打上标签,比如 颜值逆天
、暖烘烘
、高富帅
等等。高富帅并不是某一个人的专利,一个人可以被别人打上多个标签,一个标签也可以打在多个人上面。这就是多对多关系。
声明多对多关系需要用到belongsToMany
方法。
User.beblongsToMany(Tag, {through: 'user_tag'});
Tag.belongsToMany(User, {through: 'user_tag'});
在多对多关系的表结构中,无论我们把关系 id 存在双方的任何一个表中,会出现上一节所提到的使用Book.hasOne(User)
声明关系,有数据冗余的问题,所以在多对多关系下的表结构需要第三个表来保存它们之间的关系。
而这第三张表,就是上面的 user_tag 。里面有一个 userId 和一个 tagId 字段。
实例
1.新建 tag.ts 文件
import Sequelize from 'sequelize';
import {UserAttributes, UserInstance} from './user';
export interface TagAttributes {
name: string;
}
export interface TagInstance extends Sequelize.Instance<TagAttributes>, TagAttributes {
id: number;
getUsers: Sequelize.BelongsToManyGetAssociationsMixin<UserInstance>,
addUsers: Sequelize.BelongsToManyAddAssociationsMixin<UserInstance, number, any>,
addUser: Sequelize.BelongsToManyAddAssociationMixin<UserInstance, number, any>,
setUser: Sequelize.BelongsToManySetAssociationsMixin<UserInstance, number, any>,
countUsers: Sequelize.BelongsToManyCountAssociationsMixin,
createUser: Sequelize.BelongsToManyCreateAssociationMixin<UserAttributes, UserInstance, any>,
hasUser: Sequelize.BelongsToManyHasAssociationMixin<UserInstance, number>,
hasUsers: Sequelize.BelongsToManyHasAssociationsMixin<UserInstance, number>,
removeUser: Sequelize.BelongsToManyRemoveAssociationMixin<UserInstance, number>,
removeUsers: Sequelize.BelongsToManyRemoveAssociationsMixin<UserInstance, number>,
}
export default function TagDefine(sequelize: Sequelize.Sequelize, dataTypes: Sequelize.DataTypes): Sequelize.Model<TagInstance, TagAttributes> {
const S = dataTypes;
const Tag = sequelize.define<TagInstance, TagAttributes>('Tag', {
name: S.STRING
}, {
timestamps: false
});
(Tag as any).associate = function(this: typeof Tag, models){
this.belongsToMany(models.User, {through: 'user_tag'});
}
return Tag;
}
2.在 user.ts 添加关系代码
getTags: Sequelize.BelongsToManyGetAssociationsMixin<TagInstance>,
addTags: Sequelize.BelongsToManyAddAssociationsMixin<TagInstance, number, any>,
addTag: Sequelize.BelongsToManyAddAssociationMixin<TagInstance, number, any>,
setTag: Sequelize.BelongsToManySetAssociationsMixin<TagInstance, number, any>,
countTags: Sequelize.BelongsToManyCountAssociationsMixin,
createTag: Sequelize.BelongsToManyCreateAssociationMixin<TagAttributes, TagInstance, any>,
hasTag: Sequelize.BelongsToManyHasAssociationMixin<TagInstance, number>,
hasTags: Sequelize.BelongsToManyHasAssociationsMixin<TagInstance, number>,
removeTag: Sequelize.BelongsToManyRemoveAssociationMixin<TagInstance, number>,
removeTags: Sequelize.BelongsToManyRemoveAssociationsMixin<TagInstance, number>,
(User as any).associate = function(this: typeof User,models){
// this.hasOne(models.Book);
this.hasMany(models.Book);
this.belongsToMany(models.Tag, { through: 'user_tag'});
}
3.在 index.ts 里面添加验证代码
import TagDefined, {TagAttributes, TagInstance} from './tag';
const Tag = sequelize.import<TagInstance, TagAttributes>('./tag');
let user = await User.create({email:'belovedyogurt@gmail.com',name: 'yugo'})
await user.createTag({name: '萌新'}); // 为 yugo 添加一个标签
let tag = (await Tag.findAll())[0]; // 拿到 tag 表中第一条数据
const tagUser = (await tag.getUsers())[0]; // 拿到该标签关联的用户的第一个
console.log(user.id == tagUser.id); // 俩边查出来的 user 是否相等
运行之后可以得到一个 true ,说明逻辑正确。而且在数据库中也创建了user_tag
关联表,完成以上代码运行之后便可看到数据库中已存数据。
当前内容版权归 nodelover.me 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 nodelover.me .