如何在sequelize中实现多对多关联 [英] How to implement many to many association in sequelize

查看:19
本文介绍了如何在sequelize中实现多对多关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个表:Books 和 Articles,它们之间存在多对多关系.连接表是 BookArticles.

models/books.js

module.exports = function(sequelize, DataTypes) {return Food = sequelize.define("Book", {ID: {类型:DataTypes.INTEGER,主键:真,允许空:假,自动增量:真,唯一:真}});}

models/articles.js

module.exports = function(sequelize, DataTypes) {return Food = sequelize.define("Article", {ID: {类型:DataTypes.INTEGER,主键:真,允许空:假,自动增量:真,唯一:真}});}

models/bookArticles.js

module.exports = function(sequelize, DataTypes) {return Food = sequelize.define("BookArticles", {ID: {类型:DataTypes.INTEGER,主键:真,允许空:假,自动增量:真,唯一:真},书名:{类型:DataTypes.INTEGER,参考:书",参考键:'id',允许空:假},文章编号:{类型:DataTypes.INTEGER,参考:文章",参考键:'id',允许空:假},});}

还有models/index.js

m.BookArticles.belongsTo(m.Book);m.Book.hasMany(m.Article, {通过: m.BookArticles});m.BookArticles.belongsTo(m.Article);m.Article.hasMany(m.Books, {通过: m.BookArticles});

但我无法获得书籍文章

我怎样才能得到它??

解决方案

Sequelize Association Cheatsheet

为 Sequelize v2/3/4/5 更新

总的来说,我认为问题在于我们对创建什么表以及关联获得什么方法感到困惑.

<块引用>

注意:定义 foreignKey 或交叉表名称是可选的.Sequelize 会自动创建它,但定义它允许编码人员读取模型并找出外键/交叉表名称是什么,而不是猜测或需要访问数据库.

TLDR;

O:O

//两边都要定义外键.Parent.hasOne(孩子,{foreignKey:'Parent_parentId'})//父母_父母ID"列将存在于belongsTo"中.桌子.Child.belongsTo(父母,{foreignKey:'Parent_parentId'})

O:M

Parent.hasMany(Child, {foreignKey: 'Parent_parentId'})Child.belongsTo(父母,{foreignKey:'Parent_parentId'})

N:M

Parent.belongsToMany(孩子,{//这可以是字符串(模型名称)或 Sequelize 模型对象类//自 v2 以来,通过是强制性的通过:'Parent_Child',//明白了//请注意,这是 Parent 的 Id,而不是 Child.foreignKey: 'Parent_parentId'})/*上面写着:父母"属于许多孩子",并记录在Parent_child"中.表,使用父母"的 ID.*/Child.belongsToMany(家长,{通过:'Parent_Child',//明白了//请注意,这是孩子的 ID,而不是父母.foreignKey: 'Child_childId'})

<块引用>

为什么要冗长的Parent_parentId"?而不仅仅是parentId"?这是为了清楚地表明它是属于父级"的外键.在大多数情况下,只需使用更简洁的parentId"即可.*

Associations 为您提供 2 个功能:(1) 急切加载和 (2) DAO 方法:

1.包括(急切加载)

DB.Parent.findOne({其中:{ id:1},包括:[ DB.Child ]}).then(父 => {//你应该得到 `parent.Child` 作为一个子数组.})

2.hasOne()、hasMany()和belongsTo()/belongsToMany()获得的方法

关联提供数据访问对象 (DAO) 方法:

有一个():

在设置 Parent.hasOne(Child) 时,parent DAO 实例可用的方法:

DB.Parent.findOne({ where: { id: 1 } }).then(parent => {//`parent` 是 DAO//您可以使用以下任何一种方法:父.getChildparent.setChildparent.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,//属于ToManychild.getParents,child.setParents,child.createParents,

你也可以有多个关系

亲生父母/孩子

//一个父母可以有很多孩子Parent.belongsToMany(孩子,{如:自然",通过:'Parent_Child',foreignKey: 'Parent_parentId'})//一个孩子必须至少有 2 个父母(亲生父母)Child.belongsToMany(父母,{如:自然",通过:'Parent_Child',foreignKey: 'Child_childId'})

寄养父母/儿童

Parent.belongsToMany(Child, {如:福斯特",通过:'Parent_Child',foreignKey: 'Parent_parentId'})Child.belongsToMany(父母,{如:福斯特",通过:'Parent_Child',foreignKey: 'Child_childId'});

上面将创建 Parent_Child 交叉表,带有 NaturalIdFosterId.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆