最近在项目中使用了sequelize的多表联查记录一下
在sequelize中,表与表之间用代码来说存在三种关联关系:一对一,一对多,多对多
一对一
hasOne()和belongsTo()第一个参数为本表关联的另外一个表的Model实例,第二个参数中,都有foreginKey属性,对hasOne来说,这个属性值是对方表与自己Id对应的字段,对belongsTo来说,这个属性值是本表上的与对方表id对应的字段名。belongsTo比hasOne多了个targetKey属性,其为对方表的对应主键名
一对一的方法有:hasOne(Model, {foreignKey:对方,})和belongsTo(Model,{foreignKey:自己,targetKey:对方})
一对多
has开头的方法中,foreginKey属性值从对方的表上找,如果有targetKey的值则是自己的主键;
belongs开头的方法中,foreginKey属性值在自身表上找,targetKey属性值则是对方表上
一对多的方法有: hasMany(Model,{foreignKey:对方, targetKey:自己})和belongsTo(Model,{foreignKey:自己,targetKey:对方})
多对多
在Model的实例里面,重写Model的associate方法,将关联的关系放到里面。
多对多的方法有: belongsToMany(Model,{through:Model, targetKey:自己, otherKey:对方})
使用方式
1、在model中定义表之间的关系
const DistributionRepair = app.model.define('distribution_repair', {
id: { type: INTEGER, allowNull: false}
})
// 重写associate方法 ,定义与其他表之间的关系
DRepair.associate = function () {
app.model.DRepair.hasMany(app.model.DReply, { foreignKey: 'belong_repair', target: 'id' })
}
return DistributionRepair
2、 service层处理sequelize方法findAll中的include参数
// 文件名 DRepair service层
async associateList({ offset = 0, limit = 10, where = {}, models = [] }, mod) {
const { ctx, config,} = this
let include
let cache
if (models.length > 0) {
include = models.map(key => ({
model: app.model[key]
}))
}
cache = await ctx.model[mod].findAndCountAll({
where,
include,
offset,
limit,
order: [['id', 'ASC']],
})
return cache
}``
3、controll层调用service返回处理数据
// query list DRepair controller层
const mod = 'DRepair'
async index() {
const { ctx } = this
const {pageNum = 1, pageSize = 10} = ctx.request.query
const offset = (pageNum - 1) * pageSize - 0
const limit = pageSize - 0
let res = await ctx.service.DRepair.associateList({offset, limit, models: ['DReply']}, mod)
ctx.body = {
status: 0,
data: {
datas: res.rows,
total: res.count
}
}
}