资讯专栏INFORMATION COLUMN

Sequelizejs 关联

Thanatos / 3203人阅读

摘要:看似一对一其实一对多这里的指的应该是查询数据主表结果中关联信息是以单个形式作为一个属性挂在主表每一个对象中实际上是主表与关联表的多对一关系拿中的和中的进行关联配置的别名配置中的外键字段名称,默认为配置中的目标键字段名称,默认为主键查

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 = {
  : ,
  : ,
  ...
  : 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 = {
  : ,
  : ,
  ...
  : 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: "",
      ...
    }
  }]
}]

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104016.html

相关文章

  • sequelize新增字段

    摘要:使用来操作数据库,但是项目进行到后期肯定会有字段的新增一般都有操作。在程序运行时调用,把跟数据表同步。而需要你手动定义数据库迁移。定义迁移升级,定义回滚,回滚一般用不到。文档模型新增字段会自动在数据库中添加 使用sequelize来操作数据库,但是项目进行到后期肯定会有字段的新增. 1.ORM一般都有sync操作。在程序运行时调用,把model跟数据表同步。 而sequelize需要你...

    raledong 评论0 收藏0
  • 实用的开源百度云分享爬虫项目yunshare - 安装篇

    摘要:今天开源了一个百度云网盘爬虫项目,地址是。推荐使用命令安装依赖,最简单的安装方式更多安装的命令可以去上面找。启动项目使用进行进程管理,运行启动所有的后台任务,检查任务是否正常运行可以用命令,正常运行的应该有个任务。 今天开源了一个百度云网盘爬虫项目,地址是https://github.com/callmelanmao/yunshare。 百度云分享爬虫项目 github上有好几个这样的...

    lei___ 评论0 收藏0

发表评论

0条评论

Thanatos

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<