跳至主要内容
版本: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

query 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,
});

绑定参数

绑定参数类似于替换。不同之处在于替换在查询发送到数据库之前被转义并插入到查询中,而绑定参数在 SQL 查询文本之外发送到数据库。查询可以同时包含绑定参数或替换。绑定参数通过 $1、$2、...(数字)或 $key(字母数字)来引用。这与方言无关。

  • 如果传入一个数组,$1 将绑定到数组中的第一个元素(bind[0]
  • 如果传入一个对象,$key 将绑定到 object['key']。每个键必须以非数字字符开头。$1 不是有效的键,即使 object['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,
},
);