查询构建器
Lucid 查询生成器允许你编写和执行 SQL 查询。它建立在 Knex.js 之上,几乎没有自以为是的变化。
我们将查询构建器分为以下几类:
- 标准查询构建器允许为 select、update 和 delete 操作构建 SQL 查询。
- 插入查询构建器允许为 insert 操作构建 SQL 查询。
- 原始查询构建器允许从原始 SQL 字符串编写和执行查询。
选择查询#
你可以通过使用 .query
方法创建查询构建器实例来执行选择操作。
import Database from '@ioc:Adonis/Lucid/Database'
const users = await Database
.query() // 👈 给定一个选择查询构建器的实例
.from('users')
.select('*')
也可以通过直接调用 .from
方法来创建查询构建器实例。
import Database from '@ioc:Adonis/Lucid/Database'
const users = await Database
.from('users') // 👈 给定一个选择查询构建器的实例
.select('*')
插入查询#
插入查询构建器公开 API 以向数据库插入新行,你可以使用 .insertQuery
方法获取查询构建器的实例。
import Database from '@ioc:Adonis/Lucid/Database'
await Database
.insertQuery() // 👈 给定一个插入查询构建器的实例
.table('users')
.insert({ username: 'virk', email: 'virk@adonisjs.com' })
你还可以通过直接调用 .table
方法来创建查询构建器实例。
await Database
.table('users') // 👈 给出了一个插入查询构建器的实例
.insert({ username: 'virk', email: 'virk@adonisjs.com' })
多行插入#
你可以使用 .multiInsert
方法在单个插入查询中插入多行。
注意:MySQL 和 SQLite 只返回最后一行的 id,而不是所有行。
await Database.table('users').multiInsert([
{ username: 'virk' },
{ username: 'romain' },
])
原始查询#
原始查询允许从字符串输入执行 SQL 语句。当你想要执行标准查询生成器不支持的复杂查询时,这通常很有用。
你可以使用 .rawQuery
方法创建原始查询构建器的实例。它接受 SQL 字符串作为第一个参数,并将其位置 / 命名的绑定作为第二个参数。
import Database from '@ioc:Adonis/Lucid/Database'
const user = await Database
.rawQuery('select * from users where id = ?', [1])
扩展查询构建器#
你可以使用 macros 和 getters 扩展查询构建器类。扩展查询构建器的最佳位置是在自定义服务内部。
打开预设的 providers/AppProvider.ts
文件并在 boot
方法中写入以下代码。
import { ApplicationContract } from '@ioc:Adonis/Core/Application'
export default class AppProvider {
constructor(protected app: ApplicationContract) {}
public async boot() {
const {
DatabaseQueryBuilder
} = this.app.container.use('Adonis/Lucid/Database')
DatabaseQueryBuilder.macro('getCount', async function () {
const result = await this.count('* as total')
return BigInt(result[0].total)
})
}
}
在上面的示例中,我们在 数据库查询构建器 上添加了一个 getCount
方法。该方法将 count
函数添加到查询中,立即执行它并将结果作为 BigInt 返回。
通知 TypeScript 该方法#
getCount
属性是在运行时添加的,因此 TypeScript 不知道它。为了通知 TypeScript,我们将使用 声明合并 并将属性添加到 DatabaseQueryBuilderContract
接口。
Informing TypeScript about the method#
在路径 contracts/database.ts
处创建一个新文件 (文件名不重要) 并将以下内容粘贴到其中。
// 文件名: contracts/database.ts
declare module '@ioc:Adonis/Lucid/Database' {
interface DatabaseQueryBuilderContract<Result> {
getCount(): Promise<BigInt>
}
}
测试运行#
让我们尝试使 用 getCount
方法,如下所示:
await Database.query().from('users').getCount()
扩展 ModelQueryBuilder#
与 DatabaseQueryBuilder
相似,你也可以扩展 ModelQueryBuilder
运行时代码#
const {
ModelQueryBuilder
} = this.app.container.use('Adonis/Lucid/Database')
ModelQueryBuilder.macro('getCount', async function () {
const result = await this.count('* as total')
return BigInt(result[0].$extras.total)
})
扩展类型定义#
declare module '@ioc:Adonis/Lucid/Orm' {
interface ModelQueryBuilderContract<
Model extends LucidModel,
Result = InstanceType<Model>
> {
getCount(): Promise<BigInt>
}
}
用法#
import User from 'App/Models/User'
await User.query().getCount()
扩展 InsertQueryBuilder#
你也可以扩展 InsertQueryBuilder
运行时代码#
const {
InsertQueryBuilder
} = this.app.container.use('Adonis/Lucid/Database')
InsertQueryBuilder.macro('customMethod', async function () {
// 执行
})
扩展类型定义#
declare module '@ioc:Adonis/Lucid/Database' {
interface InsertQueryBuilderContract<Result = any> {
customMethod(): Promise<any>
}
}
用法#
import Database from '@ioc:Adonis/Lucid/Database'
await Database.insertQuery().customMethod()
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。