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.primaryKeyotherKey
设置 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: '',
...
}
}]
}]