原始查詢
由於在許多情況下,執行原始 / 已準備好的 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,
},
);