跳至主要內容
版本:v6 - 穩定版

原始查詢

由於在許多情況下,執行原始 / 已準備好的 SQL 查詢會更容易,因此您可以使用 sequelize.query 方法。

預設情況下,此函式會傳回兩個引數 - 一個結果陣列,以及一個包含元資料(例如受影響的列數等)的物件。請注意,由於這是原始查詢,元資料是特定於方言的。某些方言會將元資料「置於」結果物件中(作為陣列的屬性)。但是,總是會傳回兩個引數,但對於 MSSQL 和 MySQL,它們將是同一個物件的兩個參考。

const [results, metadata] = await sequelize.query('UPDATE users SET y = 42 WHERE x = 12');
// Results will be an empty array and metadata will contain the number of affected rows.

如果您不需要存取元資料,您可以傳入查詢類型來告訴 sequelize 如何格式化結果。例如,對於簡單的 select 查詢,您可以執行以下操作

const { QueryTypes } = require('sequelize');
const users = await sequelize.query('SELECT * FROM `users`', {
type: QueryTypes.SELECT,
});
// We didn't need to destructure the result here - the results were returned directly

還有其他幾種查詢類型可用。請查看原始碼以了解詳細資訊

第二個選項是模型。如果您傳入模型,則傳回的資料將會是該模型的實例。

// Callee is the model definition. This allows you to easily map a query to a predefined model
const projects = await sequelize.query('SELECT * FROM projects', {
model: Projects,
mapToModel: true, // pass true here if you have any mapped fields
});
// Each element of `projects` is now an instance of Project

請在查詢 API 參考中查看更多選項。以下是一些範例

const { QueryTypes } = require('sequelize');
await sequelize.query('SELECT 1', {
// A function (or false) for logging your queries
// Will get called for every SQL query that gets sent
// to the server.
logging: console.log,

// If plain is true, then sequelize will only return the first
// record of the result set. In case of false it will return all records.
plain: false,

// Set this to true if you don't have a model definition for your query.
raw: false,

// The type of query you are executing. The query type affects how results are formatted before they are passed back.
type: QueryTypes.SELECT,
});

// Note the second argument being null!
// Even if we declared a callee here, the raw: true would
// supersede and return a raw object.
console.log(await sequelize.query('SELECT * FROM projects', { raw: true }));

「點」屬性和 nest 選項

如果表格的屬性名稱包含點,則可以透過設定 nest: true 選項,將產生的物件變成巢狀物件。這是透過底層的 dottie.js 來實現的。請參閱以下內容

  • 沒有 nest: true

    const { QueryTypes } = require('sequelize');
    const records = await sequelize.query('select 1 as `foo.bar.baz`', {
    type: QueryTypes.SELECT,
    });
    console.log(JSON.stringify(records[0], null, 2));
    {
    "foo.bar.baz": 1
    }
  • nest: true

    const { QueryTypes } = require('sequelize');
    const records = await sequelize.query('select 1 as `foo.bar.baz`', {
    nest: true,
    type: QueryTypes.SELECT,
    });
    console.log(JSON.stringify(records[0], null, 2));
    {
    "foo": {
    "bar": {
    "baz": 1
    }
    }
    }

替換

查詢中的替換可以透過兩種不同的方式完成,使用具名參數(以 : 開頭)或不具名參數(以 ? 表示)。替換是在選項物件中傳入的。

  • 如果傳入陣列,則會按照它們在陣列中出現的順序替換 ?
  • 如果傳入物件,則 :key 將會被該物件中的鍵替換。如果物件包含查詢中找不到的鍵,或反之,則會拋出例外。
const { QueryTypes } = require('sequelize');

await sequelize.query('SELECT * FROM projects WHERE status = ?', {
replacements: ['active'],
type: QueryTypes.SELECT,
});

await sequelize.query('SELECT * FROM projects WHERE status = :status', {
replacements: { status: 'active' },
type: QueryTypes.SELECT,
});

會自動處理陣列替換,以下查詢會搜尋狀態符合值陣列的專案。

const { QueryTypes } = require('sequelize');

await sequelize.query('SELECT * FROM projects WHERE status IN(:status)', {
replacements: { status: ['active', 'inactive'] },
type: QueryTypes.SELECT,
});

若要使用萬用字元 %,請將其附加到您的替換。以下查詢會比對名稱以 'ben' 開頭的使用者。

const { QueryTypes } = require('sequelize');

await sequelize.query('SELECT * FROM users WHERE name LIKE :search_name', {
replacements: { search_name: 'ben%' },
type: QueryTypes.SELECT,
});

綁定參數

綁定參數與替換類似。不同之處在於,替換會由 sequelize 轉義並插入查詢中,然後再將查詢傳送到資料庫,而綁定參數則會在 SQL 查詢文字之外傳送到資料庫。一個查詢可以有綁定參數或替換。綁定參數以 $1、$2、...(數字)或 $key(字母數字)來表示。這與方言無關。

  • 如果傳入陣列,則 $1 會綁定到陣列中的第一個元素(bind[0]
  • 如果傳入物件,則 $key 會綁定到 object['key']。每個鍵都必須以非數字字元開頭。即使 object['1'] 存在,$1 也不是有效的鍵。
  • 在這兩種情況下,都可以使用 $$ 來轉義文字 $ 符號。

陣列或物件必須包含所有綁定值,否則 Sequelize 會拋出例外。即使在資料庫可能會忽略綁定參數的情況下,也適用此規則。

資料庫可能會對此增加更多限制。綁定參數不能是 SQL 關鍵字,也不能是表格或欄名稱。它們也會在引號文字或資料中被忽略。在 PostgreSQL 中,如果無法從內容推斷類型,可能還需要將它們強制轉換為類型 $1::varchar

const { QueryTypes } = require('sequelize');

await sequelize.query(
'SELECT *, "text with literal $$1 and literal $$status" as t FROM projects WHERE status = $1',
{
bind: ['active'],
type: QueryTypes.SELECT,
},
);

await sequelize.query(
'SELECT *, "text with literal $$1 and literal $$status" as t FROM projects WHERE status = $status',
{
bind: { status: 'active' },
type: QueryTypes.SELECT,
},
);