使用sequelize框架做一些简单的查,但是有些时候,做一些复杂的子查询时,我们就不能完全依赖sequelize给我们提供的方法了,那么我们如何借助sequelize来帮我做复杂的子查询而又不用自己手写整个原始查询呢?
这里就要介绍到sequelize的literal方法,sequelize.literal实用程序功能结合使用,会直接在查询中插入任意内容,而不会自动转义,这就意味着我们需要进行子查询到时候,不必把完整的sql语句全写出来,只需要写子查询sql语句。
但是要注意,由于
sequelize.literal会直接插入内容到sql语句中,不进行任何转译,所以这可能造成安全隐患,所以我们在使用这个方法时必须要清楚自己写的是什么,最好不要用在用户输入的内容上
接下来介绍使用方法
首先定义模型(model)
import { Table,Column, Model, PrimaryKey, AutoIncrement,ForeignKey, HasMany, BelongsTo} from "sequelize-typescript";
@Table
class Comany extends Model {
@PrimaryKey //主键
@AutoIncrement //自增
@Column
id:number
@Column
name:string
// 定义关系
@HasMany(() => Staff)
staff:Staff[]
}
@Table
class Staff extends Model{
@PrimaryKey
@AutoIncrement
@Column
id:number
@ForeignKey(() => Comany) //定义company_id为外键
@Column
company_id:number
@Column
name:string
@Column
age:number //年龄
@Column
salary:number // 工资
//定义关系
@BelongsTo(() => Comany)
company:Comany
}
这里我们定义了公司表和员工表,并且把它们关联起来,具体的表与表直接关联可以看我上一篇文章# sequelize-typescript的多表查询。
假如我们需要查询所有的公司数据,并且查询每个公司年龄大于30岁的有多少的员工,这里用sequelize提供的简单方法查询就很难办到,这时候就要请出sequelize.literal,先上代码:
//查询id为1的公司信息以及其所有的员工信息(员工id和员工姓名)
Comany.findAll({
attributes: {
include: [
[
// 注意括号,别漏掉了!
sequelize.literal(`(
SELECT COUNT(*)
FROM staffs AS staff
WHERE
staff.company_id = company.id
AND
staff.age > 30
)`),
'staff_count'
]
]
}
})
我们把原始sql语句也写一下,对比一下
SELECT
*,
(
SELECT COUNT(*)
FROM staffs AS staff
WHERE
staff.company_id = company.id
AND
staff.age > 30
) AS staff_count
FROM companys AS companys
得到查询结果
[
{
"id": 1,
"name": "某宝",
"staff_count": 3000
},
{
"id": 2,
"name": "某度",
"staff_count": 200
}
]
我这里只是做了简单的演示,实际开发中肯定会比这复杂很多,具体详细的sequelize子查询可以参考官网api