欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Sequelizejs关联-外籍杰克-SegmentFault思否

程序员文章站 2022-06-13 14:47:03
one-to-one 看似一对一,其实一对多.这里的 one-to-one 指的应该是查询数据(主表)结果中,关联信息是以单个形式作为一个属性挂在主表每一个对象中 实际上是,主表与...

one-to-one

看似一对一,其实一对多.这里的 one-to-one 指的应该是查询数据(主表)结果中,关联信息是以单个形式作为一个属性挂在主表每一个对象中

实际上是,主表与关联表的多对一关系.

belongsto

sourcemodel.belongsto(targetmodel, { as, foreignkey, targetkey })

拿 sourcemodel 中的 foreignkey 和 targetmodel 中的 targetkey 进行关联.
as 配置 targetmodel 的别名
foreignkey 配置 sourcemodel 中的外键字段名称,默认为 ${as || targetmodel.name}+${targetmodel.primarykey}
targetkey 配置 targetmodel 中的目标键字段名称,默认为 targetmodel 主键

查询出来结果结构如:

const sourceobj = {
  <sourceobjattr>: <value>,
  <sourceobjattr>: <value>,
  ...
  <as || targetmodel.name>: targetobj
}

sourcemodel 中存在 foreignkey 关联 targetmodel,比如:

player.belongsto(team)

foreignkey 用来自定义 sourcemodel 中的外键名称.比如:

user.belongsto(company, { foreignkey: 'cid' }) // user.cid 即外键

默认情况下,foreignkey 值为${team.name}+${team.primarykey}.注意这里的连接是根据 source model 的配置而决定是 camelcase 还是 underscored.例如:

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.比如:

user.belongsto(company, { foreignkey: 'cid', targetkey: 'uuid' }) // 即将 user.cid 与 company.uuid 进行关联

as 用来转换 targetmodel 的 name. 这里有两个方面,一个是在生成 foreignkey 时替换 targetmodel name,一个是在拼装查询结果时,改变 targetmodel 作为 sourcemodel 中的属性的名称.比如:

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}

查询结构为:

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

比如:

player 表,teamid 关联 team 表 coach 表 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: '',
      ...
    }
  }]
}]