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);
    }).call(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解析錯誤,等遇到了再來更新


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM