原生查询构建器
原始查询构建器允许你从 SQL 字符串执行查询。即使你直接执行原始 SQL 字符串,仍然可以通过对值使用占位符来保护查询免受 SQL 注入的影响。
执行查询
以下是从 SQL 字符串执行查询的示例。
执行原始查询时,底层驱动程序的结果将按原样返回。
import Database from '@ioc:Adonis/Lucid/Database'
await Database.rawQuery('select * from users')
使用绑定
防止你的查询受到 SQL 注入。你永远不应将用户输入直接硬编码到查询中,而应依赖占位符和绑定。 例如:
位置占位符
Database.rawQuery(
'select * from users where id = ?',
[1]
)
// SELECT * FROM "users" WHERE "id" = 1
你还可以使用绑定传入动态列名。 ??
被解析为列名,而 ?
被解析为值。
Database.rawQuery(
'select * from users where ?? = ?',
['users.id', 1]
)
// SELECT * FROM "users" WHERE "users"."id" = 1
命名占位符
你还可以命名占位符,然后使用对象来定义绑定。 例如:
Database.rawQuery(
'select * from users where id = :id',
{
id: 1,
}
)
使用动态列名时,你还需要在占位符后附加冒号 :
。
Database.rawQuery(
'select * from users where :column: = :value',
{
column: 'id',
value: 1,
}
)
另一个比较两列的例子。
Database.rawQuery(
'select * from user_logins inner join users on :column1: = :column2:',
{
column1: 'users.id',
column2: 'user_logins.user_id',
}
)
/**
SELECT * FROM
user_logins
INNER JOIN
users
ON
"users"."id" = "user_logins"."user_id"
*/
原始查询与原始值
有两种方法可以使用 Database
模块创建原始查询。
Database.rawQuery('select * from users')
和
Database.raw('select * from users')
rawQuery
可以通过使用 await
关键字或链接 then/catch
方法来执行。
但是,raw
方法的输出是为了在其他查询中使用。 例如
await Database.select(
'id',
Database.raw('select ip_address from user_logins'),
)
方法/属性
以下是原始查询构建器上可用的方法和属性列表。
包装
用前缀和后缀包装原始查询。 在将原始查询作为参考传递时通常很有帮助。
await Database.select(
'id',
Database
.raw('select ip_address from user_logins')
.wrap('(', ')'),
)
debug
debug
方法允许在单个查询级别启用或禁用调试。 这是关于调试查询的完整指南。
await Database
.rawQuery('select * from users')
.debug(true)
timeout
为查询定义“超时”。 超过超时后引发异常。
timeout 的值始终以毫秒为单位。
await Database
.rawQuery('select * from users')
.timeout(2000)
你还可以在 MySQL 和 PostgreSQL 使用超时时取消查询。
await Database
.rawQuery('select * from users')
.timeout(2000, { cancel: true })
客户端
参考底层数据库查询客户端的实例。
const query = Database.rawQuery(sql, bindings)
console.log(query.client)
knexQuery
对底层 KnexJS 查询实例的引用。
const query = Database.rawQuery(sql, bindings)
console.log(query.knexQuery)
reporterData
查询构建器发出 db:query
事件,并使用框架分析器报告查询执行时间。
使用 reporterData
方法,你可以将其他详细信息传递给事件和分析器。
Database
.rawQuery(sql, bindings)
.reporterData({ userId: auth.user.id })
现在在 db:query
事件中,你可以访问 userId
的值,如下所示。
Event.on('db:query', (query) => {
console.log(query.userId)
})
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。