orm框架sequelize的where条件接受动态参数传入

      在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

                     

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值