如何在 sequelize 中实现多对多关联 [英] How to implement many to many association in sequelize
问题描述
我有两个表:Books 和 Articles,它们之间存在多对多关系.联接表是 BookArticles.
模型/books.js
module.exports = function(sequelize, DataTypes) {return Food = sequelize.define("Book", {ID: {类型:DataTypes.INTEGER,主键:真,allowNull: 假,自动增量:真,独特:真实}});}
模型/文章.js
module.exports = function(sequelize, DataTypes) {return Food = sequelize.define("文章", {ID: {类型:DataTypes.INTEGER,主键:真,allowNull: 假,自动增量:真,独特:真实}});}
模型/bookArticles.js
module.exports = function(sequelize, DataTypes) {return Food = sequelize.define("BookArticles", {ID: {类型:DataTypes.INTEGER,主键:真,allowNull: 假,自动增量:真,独特:真实},书号:{类型:DataTypes.INTEGER,参考资料:书",参考密钥:'id',allowNull: 假},文章 ID:{类型:DataTypes.INTEGER,参考文献:文章",参考密钥:'id',allowNull: 假},});}
和模型/index.js
m.BookArticles.belongsTo(m.Book);m.Book.hasMany(m.Article, {through: m.BookArticles});m.BookArticles.belongsTo(m.Article);m.Article.hasMany(m.Books, {through: m.BookArticles});
但我无法获得书籍文章
我怎样才能得到它??
Sequelize Association Cheatsheet
针对 Sequelize v2/3/4/5 进行了更新
总的来说,我认为问题在于我们对创建的表以及关联获得的方法感到困惑.
<块引用>注意:定义外键或交叉表名称是可选的.Sequelize 自动创建它,但定义它允许编码人员读取模型并找出外键/交叉表名称是什么,而不是猜测或需要访问数据库.
TLDR;
O:O
//两边都要定义外键.Parent.hasOne(Child, {foreignKey: 'Parent_parentId'})//"Parent_parentId";列将存在于belongsTo"中桌子.Child.belongsTo(Parent, {foreignKey: 'Parent_parentId'})
O:M
Parent.hasMany(Child, {foreignKey: 'Parent_parentId'})Child.belongsTo(Parent, {foreignKey: 'Parent_parentId'})
N:M
Parent.belongsToMany(孩子,{//这可以是字符串(模型名称)或 Sequelize 模型对象类//从 v2 开始,通过是强制性的通过:'Parent_Child',//陷阱//请注意,这是 Parent 的 Id,而不是 Child.外键:'Parent_parentId'})/*上面写着:《父母》属于许多孩子",并记录在Parent_child"中.表,使用父母"的 ID.*/Child.belongsToMany(家长,{通过:'Parent_Child',//陷阱//请注意,这是孩子的 ID,而不是父母.外键:'Child_childId'})
<块引用>
为什么冗长的Parent_parentId"而不仅仅是parentId"?这是为了明确它是属于父"的外键.在大多数情况下,只需使用更简洁的parentId"即可.*
Associations 为您提供 2 个功能:(1) Eager loading 和 (2) DAO 方法:
1.包括(急切加载)
DB.Parent.findOne({其中:{ id: 1 },包括:[ DB.Child ]}).那么(父母=> {//你应该得到 `parent.Child` 作为一个孩子的数组.})
2.hasOne()、hasMany()和belongsTo()/belongsToMany()获得的方法
关联提供数据访问对象 (DAO) 方法:
有一个():在设置Parent.hasOne(Child)
时,parent
DAO实例可用的方法:
DB.Parent.findOne({ where: { id: 1 } }).then(parent => {//`parent` 是 DAO//您可以使用以下任何一种方法:父.getChild父.setChild父.addChildparent.createChildparent.removeChildparent.hasChild})
有很多():
在设置Parent.hasMany(Child)
时,parent
DAO实例可用的方法:
parent.getChildren,parent.setChildren,parent.addChild,parent.addChildren,parent.createChild,parent.removeChild,parent.hasChild,parent.hasChildren,
属于()/属于多:
在设置Child.belongsTo(Parent)
时,child
DAO实例可用的方法:
child.getParent,child.setParent,child.createParent,//属于多child.getParents,child.setParents,child.createParents,
你也可以有多个关系
自然父母/孩子//一个父级可以有多个子级Parent.belongsToMany(孩子,{如:自然",通过:'Parent_Child',外键:'Parent_parentId'})//一个孩子必须至少有 2 个父母(亲生父母)Child.belongsToMany(父母,{如:自然",通过:'Parent_Child',外键:'Child_childId'})
寄养父母/孩子
Parent.belongsToMany(Child, {如:'福斯特',通过:'Parent_Child',外键:'Parent_parentId'})Child.belongsToMany(父母,{如:'福斯特',通过:'Parent_Child',外键:'Child_childId'});
以上将创建带有 NaturalId
和 FosterId
的 Parent_Child
交叉表.
I have two tables: Books and Articles with a many-to-many relationship between them. Joining table is BookArticles.
models/books.js
module.exports = function(sequelize, DataTypes) {
return Food = sequelize.define("Book", {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true,
unique: true
}
});
}
models/articles.js
module.exports = function(sequelize, DataTypes) {
return Food = sequelize.define("Article", {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true,
unique: true
}
});
}
models/bookArticles.js
module.exports = function(sequelize, DataTypes) {
return Food = sequelize.define("BookArticles", {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true,
unique: true
},
bookId: {
type: DataTypes.INTEGER,
references: 'Book',
referencesKey: 'id',
allowNull: false
},
ArticleId: {
type: DataTypes.INTEGER,
references: 'Article',
referencesKey: 'id',
allowNull: false
},
});
}
And models/index.js
m.BookArticles.belongsTo(m.Book);
m.Book.hasMany(m.Article, {through: m.BookArticles});
m.BookArticles.belongsTo(m.Article);
m.Article.hasMany(m.Books, {through: m.BookArticles});
but I could not get book articles
How can I get it ??
Sequelize Association Cheatsheet
Updated for Sequelize v2/3/4/5
Generally I think the problems are that we are confused about what tables created, and what methods are gained by associations.
Note: Defining foreignKey or cross table name are optional. Sequelize automatically creates it, but defining it allows coders to read the models and find out what the foreign keys/cross table names are, instead of guessing or needing to access the database.
TLDR;
O:O
// foreign key has to be defined on both sides.
Parent.hasOne(Child, {foreignKey: 'Parent_parentId'})
// "Parent_parentId" column will exist in the "belongsTo" table.
Child.belongsTo(Parent, {foreignKey: 'Parent_parentId'})
O:M
Parent.hasMany(Child, {foreignKey: 'Parent_parentId'})
Child.belongsTo(Parent, {foreignKey: 'Parent_parentId'})
N:M
Parent.belongsToMany(
Child,
{
// this can be string (model name) or a Sequelize Model Object Class
// through is compulsory since v2
through: 'Parent_Child',
// GOTCHA
// note that this is the Parent's Id, not Child.
foreignKey: 'Parent_parentId'
}
)
/*
The above reads:
"Parents" belongs to many "Children", and is recorded in the "Parent_child" table, using "Parents"'s ID.
*/
Child.belongsToMany(
Parent,
{
through: 'Parent_Child',
// GOTCHA
// note that this is the Child's Id, not Parent.
foreignKey: 'Child_childId'
}
)
Why the verbose "Parent_parentId" and not just "parentId"? This is to make it obvious that it's a foreign key that belonged to "Parent". In most cases it's okay to just use the more succinct "parentId".*
Associations gives you 2 functionality: (1) Eager loading and (2) DAO Methods:
1. Include (Eager loading)
DB.Parent.findOne({
where: { id: 1 },
include: [ DB.Child ]
}).then(parent => {
// you should get `parent.Child` as an array of children.
})
2. Methods gained by hasOne(), hasMany() and belongsTo()/belongsToMany()
Associations give the Data Access Object (DAO) methods:
hasOne():In setting a Parent.hasOne(Child)
, methods available to parent
DAO instance:
DB.Parent.findOne({ where: { id: 1 } }).then(parent => {
// `parent` is the DAO
// you can use any of the methods below:
parent.getChild
parent.setChild
parent.addChild
parent.createChild
parent.removeChild
parent.hasChild
})
hasMany():
In setting a Parent.hasMany(Child)
, methods available to parent
DAO instance:
parent.getChildren,
parent.setChildren,
parent.addChild,
parent.addChildren,
parent.createChild,
parent.removeChild,
parent.hasChild,
parent.hasChildren,
belongsTo()/belongsToMany:
In setting a Child.belongsTo(Parent)
, methods available to child
DAO instance:
child.getParent,
child.setParent,
child.createParent,
//belongsToMany
child.getParents,
child.setParents,
child.createParents,
You can also have multiple relationships
Natural Parents/Children// a parent can have many children
Parent.belongsToMany(Child, {
as: 'Natural',
through: 'Parent_Child',
foreignKey: 'Parent_parentId'
})
// a child must at least have 2 parents (natural mother and father)
Child.belongsToMany(Parent, {
as: 'Natural',
through: 'Parent_Child',
foreignKey: 'Child_childId'
})
Foster Parents/Children
Parent.belongsToMany(Child, {
as: 'Foster',
through: 'Parent_Child',
foreignKey: 'Parent_parentId'
})
Child.belongsToMany(Parent, {
as: 'Foster',
through: 'Parent_Child',
foreignKey: 'Child_childId'
});
The above will create the Parent_Child
cross table, with NaturalId
and FosterId
.
这篇关于如何在 sequelize 中实现多对多关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!