Sequelizejs 關聯

One-To-One

看似一對一,其實一對多.這裏的 One-To-One 指的應該是查詢數據(主表)結果中,關聯信息是以單個形式做爲一個屬性掛在主表每個對象中ide

其實是,主表與關聯表的多對一關係.ui

belongsTo

SourceModel.belongsTo(TargetModel, { as, foreignKey, targetKey })

拿 SourceModel 中的 foreignKey 和 TargetModel 中的 targetKey 進行關聯.
as 配置 TargetModel 的別名
foreignKey 配置 SourceModel 中的外鍵字段名稱,默認爲 ${as || TargetModel.name}+${TargetModel.primaryKey}
targetKey 配置 TargetModel 中的目標鍵字段名稱,默認爲 TargetModel 主鍵this

查詢出來結果結構如:code

const sourceObj = {
  <sourceObjAttr>: <value>,
  <sourceObjAttr>: <value>,
  ...
  <as || TargetModel.name>: targetObj
}

SourceModel 中存在 foreignKey 關聯 TargetModel,好比:對象

Player.belongsTo(Team)

foreignKey 用來自定義 SourceModel 中的外鍵名稱.好比:ci

User.belongsTo(Company, { foreignKey: 'cid' }) // User.cid 即外鍵

默認狀況下,foreignKey 值爲${Team.name}+${Team.primaryKey}.注意這裏的鏈接是根據 source model 的配置而決定是 camelCase 仍是 underscored.例如:underscore

const User = this.sequelize.define('user', {}, { underscored: true })
const Company = this.sequelize.define('company', {
  uuid: { type: Sequelize.UUID, primaryKey: true }
})

User.belongsTo(Company) // User 的 foreignKey 爲 company_uuid

targetKey 用來指定 targetModel 中用來和 sourceModel 中外鍵進行匹配的字段名稱,默認爲 targetModel 中的 primaryKey.好比:get

User.belongsTo(Company, { foreignKey: 'cid', targetKey: 'uuid' }) // 即將 User.cid 與 Company.uuid 進行關聯

as 用來轉換 targetModel 的 name. 這裏有兩個方面,一個是在生成 foreignKey 時替換 targetModel name,一個是在拼裝查詢結果時,改變 targetModel 做爲 sourceModel 中的屬性的名稱.好比:sequelize

User.belongsTo(Company, { as: 'com' })

// foreign key would be: com_uuid
// company property of user object would be 'com'

hasOne

SourceModel.hasOne(TargetModel, { as, foreignKey })

拿 SourceModel 中的主鍵和 TargetModel 中的外鍵進行關聯
as 配置 TargetModel 的別名
foreignKey 配置 TargetModel 中的外鍵字段名稱,默認爲 ${as || SourceModel.name}+${SourceModel.primaryKey}io

查詢結構爲:

const sourceObj = {
  <sourceObjAttr>: <value>,
  <sourceObjAttr>: <value>,
  ...
  <as || TargetModel.name>: targetObj
}

TargetModel 中存在 foreignKey 關聯 SourceModel,好比:

Company.hasOne(User)

foreignKey 默認爲 ${Company.name}+${Company.primaryKey}.也能夠自定義:

Company.hasOne(User, { foreignKey: 'company_id' }) // User.company_id 爲外鍵

targetKey hasOne 中沒有 targetKey 屬性

belongsTo V.S hasOne

若是關聯信息(好比:外鍵)保存在 source 中,就是用 belongsTo;若是關聯信息保存在 target 中,則是用 hasOne

好比:

  1. Player 表,teamId 關聯 Team 表
  2. Coach 表
  3. Team 表,coachId 關聯 Coach 表
Player.belongsTo(Team) // Player.teamId -- Team.id
Coach.hasOne(Team) // Team.coachId -- Coach.id

爲何不能反過來,好比Player.belongsTo(Team)中將 source 和 target 交換下,不就能夠應用hasOne了嗎?問題就在於 source 是根據查詢要求而定的,若是是要查詢 Player,並把關聯的 Team 信息帶出來,那麼 source 就只能是 Player.

小結:根據查詢主表,即 source,找到須要查詢到的關聯表,若是關聯信息(外鍵)在 source 中,則 belongsTo,不然 hasOne.

One-To-Many

hasMany

SourceModel.hasMany(TargetModel, { as, foreignKey, sourceKey })

拿 TargetModel 中的外鍵與 SourceModal 中的主鍵關聯
as 配置 TargetModel 別名
foreignKey 配置 TargetModel 中外鍵名稱,默認爲 ${SourceModel.name}+${SourceMode.primaryKey}
soruceKey 配置 SourceModel 中關聯鍵名稱,默認爲 SourceModel.primaryKey

這裏 as 的值並不影響 key 的默認值

Many-To-Many

belongsToMany

SourceModel.belongsToMany(TargetModel, { through: AssociationModel, as, foreignKey, otherKey })

經過中間表進行關聯
as 中間表 AssociationModel 的別名
foreignKey 配置 AssociationModel 中與 SourceModel 主鍵關聯的外鍵名稱,默認爲 SourceModel.name + SourceModel.primaryKey
otherKey 配置 AssociationModel 中與 TargetModel 主鍵關聯的外鍵名稱,默認爲 TargetModel.name + TargetModel.primaryKey

這裏 as 的值並不影響 key 的默認值

User.belongsToMany(Role, { through: RoleAssignment, foreignKey: 'userId', otherKey: 'roleId' })

user.findAll({
  include: [{
    model: Role,
    through: {
      // attributes: [], // uncomment this line to hide RoleAssignment as attribute in result in target model
      model: RoleAssignment,
      where
    }
  }]
})

返回結果

const result = [{
  id: '',
  userName: '',
  gender: '',
  roles: [{
    id: '',
    roleName: '',
    ...
    RoleAssignment: {
      id: '',
      roleId: '',
      userId: '',
      ...
    }
  }]
}]
相關文章
相關標籤/搜索