• sequelize之通过options生成sql语句


    前言

    在node.js web框架中使用sequelize来作为ORM是十分方便的。但是,有的时候我们需要用到子查询语句,使用sequelize无法完成需求。这时候,

    如果你的查询语句不是很复杂,可以使用sequelize提供的query()方法直接执行生成的sql语句。

    如果你的查询语句很复杂,但是子表查询结果数据不是很多,你可以先把子表查询结果获取到,在后端代码中进行数据处理,完成其它操作。

    如果你的查询语句很复杂,并且子表查询结果数据非常多,不可能在代码中完成数据处理,简单的可以执行两次,第一次查询字表数据,获取到查询的sql语句,拼接好子查询语句后再查询一次即可。

    由于sequelize只有执行查询后才可以在logging的回调函数中获取到生成的sql语句,这样就会多执行一次无用的数据库查询,下边写一个不执行查询获取sql语句的方法。

    实例

    • 以nodejs为例
    • 根据options获取sql语句
    const Utils = require('sequelize/lib/utils');
    /**
    * @parms model 当前表的模型实例
    * @options {object} 查询参数
    */
    module.exports = function genSqlString(model, options) {
        return (function (options) {
            const tableNames = {};
            tableNames[this.getTableName(options)] = true;
            options = Utils.cloneDeep(options);
            options = Object.assign({}, options, {
                hooks: true,
                rejectOnEmpty: true,
                type: 'SELECT',
                model: this,
                tableNames: Object.keys(tableNames)
            });
            options.originalAttributes = this._injectDependentVirtualAttributes(options.attributes);
    
            if (options.include) {
                options.hasJoin = true;
    
                this._validateIncludedElements(options, tableNames);
    
                if (
                    options.attributes
                    && !options.raw
                    && this.primaryKeyAttribute
                    && !options.attributes.includes(this.primaryKeyAttribute)
                    && (!options.group || !options.hasSingleAssociation || options.hasMultiAssociation)
                ) {
                    options.attributes = [this.primaryKeyAttribute].concat(options.attributes);
                }
            }
    
            if (!options.attributes) {
                options.attributes = Object.keys(this.rawAttributes);
                options.originalAttributes = this._injectDependentVirtualAttributes(options.attributes);
            }
    
            this.options.whereCollection = options.where || null;
    
            Utils.mapFinderOptions(options, this);
    
            options = this._paranoidClause(this, options);
            return this.QueryGenerator.selectQuery(this.getTableName(options), options, this);
        }).bind(model)(options);
    };
    
    • 补充一个执行后获取sql语句的实例
    let sql = '';
    options.logging = function (str) {
        sql = str.substring(20, str.length-1); // 截取其中的sql语句
    };
    await models.OrderBasic.findAll(options); // options为查询时存入的参数
    

    总结

    1. 获取sql语句的方法实际上是将源码中生成sql语句的部分提取出来了

    2. 目前还没有遇到sql解析错误,等遇到了再来更新

  • 相关阅读:
    Swap Nodes in Pairs
    Search for a Range——稍微升级版的二分查找
    Set Matrix Zeroes——常数空间内完成
    Ubuntu系统---C++之Eclipse 开始工程项目
    Ubuntu系统---C++之Eclipse编译器 CDT插件安装
    Ubuntu系统---开机总会显示错误报告处理
    Ubuntu系统---C++之Eclipse IDE 编译器安装
    Ubuntu系统---终端下用g++进行c++项目
    Ubuntu系统---进行C++项目开发的工具
    YOLO---Darknet下的 GPU vs CPU 速度
  • 原文地址:https://www.cnblogs.com/xpengp/p/13164311.html
Copyright © 2020-2023  润新知