在nodejs项目中,接口会接收从前台传来的查询参数,接口里面根据请求参数动态查询数据库,例如分页参数等等;sequelize官方文档中并没有提及如何做,不过可以利用sequelize的特性去巧妙实现。下面介绍两种方式:
先来看第一种方式:由于sequelize的where查询条件本身就是一个对象object,所以我们可以利用这种特性,提前根据请求参数以及各种条件判断来构造这个对象,构造完以后,放进对应的查询位置就好,代码如下:
// 这是一个在前台展示用户列表的接口
static async list(req, resp) {
// 前台可能会传来nickname、account来模糊查询,以及分页参数
const {page, pageSize, nickname, account} = req.query;
// where条件接受一个对象传入,先定义一个对象,用{}符号
let criteria = {};
const start = (page - 1) * pageSize;
let total = 0;
let list = null;
// 检查前台传来的参数是否为空,从而构造各种查询条件
if (nickname) {
criteria['nickname'] = nickname;
if (account) {
// 这里用的就是纯粹的=符号,代表精确查找,下面例举了like符号,更多符号自己探索
criteria['account'] = account;
}
} else if (account) {
// 这里后面赋值的是like操作符,代表模糊查询,后面account用``反引号字符串替换模板将account代入进去
criteria['account'] = {$like: `%${account}%`};
} await UserModel.findAndCountAll({
where: criteria, // 将前面构造的对象传入
offset: start,
limit: Number(pageSize)}).then( // 由于前端使用了element-ui,传过来的pageSize是string型,要转一下
result => {
total = result.count;
list = result.rows;
});
resp.json(new result(200, {total, list}));
}
如果你都是根据前台传来的请求参数进行精确查找的话,那么上面的代码完全可以写成下面这种形式:
这是因为where: {nickname , account }这句代码,还记得我们说过where参数可以是一个对象吗,在sequelize中那句代码就代表where: {nickname: nickname , account: account },传进的参数即是参数名,本身也是参数值。如下所示:
static async list(req, resp) {
const {page, pageSize, nickname, account} = req.query;
let criteria = {};
const start = (page - 1) * pageSize;
let total = 0;
let list = null;
await UserModel.findAndCountAll({
where: {nickname , account },
offset: start,
limit: Number(pageSize)}).then(
result => {
total = result.count;
list = result.rows;
});
resp.json(new result(200, {total, list}));
}
第二种方式如下所示:它将判断条件都放到了where中,用的是三目运算符,假如条件为真,中括号里面像是在拼装原生sql语句,并且还用到了?号占位符,两个参数外面用了一个sequelize.and包裹,这个符号等同于$and,当然如果你需要其他查询方式,可以换成其他符号,例如or等等。我的项目使用了TypeScript,在我的项目中下面这种方式代码下面一直冒红
await UserModel.findAndCountAll({
where: sequelize.and(
nickname ? ['nickname = ?', nickname] : null,
account ? ['account = ?', account] : null
),
offset: start,
limit: Number(pageSize)}).then(
result => {
total = result.count;
list = result.rows;
});
如果上面代码不冒红能正常编译的话,where条件的sql语句打印出来为 where (nickname='xxxx' and account='xxxxx' ),假如account为空null的话,打印出来的sql语句为where (nickname='xxxx' and 1=1 );假如两个参数都为空,那就是where (1=1 and 1=1 );奇妙吧,对你的查询结果丝毫没有影响,因为你本来就是想要查询全部结果。总之使用了typescript的话,这种方式用不了,原始的javascript可以试一下
随后我就改良了一下,将中括号里面的语句改成反引号字符串替换模板形式,where关键词又冒红
await UserModel.findAndCountAll({
where: sequelize.and(
nickname ? `nickname = ${nickname}` : null,
account ? `account = ${account}` : null),
offset: start,
limit: Number(pageSize)}).then(
result => {
total = result.count;
list = result.rows;
});
因为sequelize和typescript语法经常冲突,所以我就想先运行试一下,运行时,调用接口,报下面的错误:Error: Support for `{where: 'raw query'}` has been removed.
我用的sequelize版本为4.41.2,可能raw 查询不支持了,或者默认关闭了,我看到有个参数为raw,可以将它设置true,我没试。
参考链接:https://github.com/sequelize/sequelize/issues/1955
https://stackoverflow.com/questions/42236837/how-to-perform-a-search-with-conditional-where-parameters-using-sequelize
https://stackoverflow.com/questions/26106165/sequelize-dynamic-query-params
https://stackoverflow.com/questions/36466395/sequelize-optional-where-clause-parameters
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)