CRUD 操作
Lucid 模型使得执行 CRUD 操作变得非常容易,并且还围绕每个操作定义了生命周期挂钩。
本指南涵盖了 80% 的用例。但是,请务必检查 Model API docs 文档以了解所有可用的方法。
创建#
你可以通过首先为模型实例分配值然后调用 save
方法来创建新记录并将其保存到数据库中。
save
方法在第一次持久化模型实例时执行 INSERT 查询,并在模型持久化时执行 UPDATE 查询。
import User from 'App/Models/User'
const user = new User()
// 分配用户名和邮箱
user.username = 'virk'
user.email = 'virk@adonisjs.com'
// 插入数据库
await user.save()
console.log(user.$isPersisted) // true
此外,你可以使用 fill
方法将所有属性定义为一次,然后调用 save
方法。
await user
.fill({ username: 'virk', email: 'virk@adonisjs.com' })
.save()
console.log(user.$isPersisted) // true
create#
static create
方法一次性创建模型实例并将其持久化到数据库中。
import User from 'App/Models/User'
const user = await User.create({
username: 'virk',
email: 'virk@adonisjs.com',
})
console.log(user.$isPersisted) // true
createMany#
创建模型的多个实例并将它们持久保存到数据库中。createMany
方法接受与 create
方法相同的选项。
注:为每个模型实例发出一个插入查询,以执行每个实例的生命周期钩子。
const user = await User.createMany([
{
email: 'virk@adonisjs.com',
password: 'secret',
},
{
email: 'romain@adonisjs.com',
password: 'secret',
},
])
读取#
你可以使用以下静态方法之一查询数据库表。
all#
从数据库中获取所有用户,该方法返回一个模型实例数组。
const user = await User.all()
// SQL: SELECT * from "users" ORDER BY "id" DESC;
find#
使用主键查找记录,该方法返回一个模型实例或 null (当没有找到记录时)。
const user = await User.find(1)
// SQL: SELECT * from "users" WHERE "id" = 1 LIMIT 1;
findBy#
按列名及其值查找记录。与 find
方法类似,该方法也返回一个模型实例或 null
。
const user = await User.findBy('email', 'virk@adonisjs.com')
// SQL: SELECT * from "users" WHERE "email" = 'virk@adonisjs.com' LIMIT 1;
first#
从数据库中获取第一条记录。没有记录时返回 null
。
const user = await User.first()
// SQL: SELECT * from "users" LIMIT 1;
orFail 组合变体#
你还可以将 orFail
变体用于查找方法,找不到行时会引发异常。
const user = await User.findOrFail(1)
const user = await User.firstOrFail()
const user = await User.findByOrFail('email', 'virk@adonisjs.com')
orFail
变体将引发 E_ROW_NOT_FOUND
异常,并带有 404
statusCode,你可以 手动处理 此异常以将其转换为所需的响应。
使用查询生成器#
上述静态方法涵盖了查询数据库的常见用例。但是,除了这些方法,你还可以利用查询构建器 API 进行高级 SQL 查询。
注意:
模型查询构建器 返回一个模型实例数组,而不是纯 JavaScript 对象。
你可以使用 .query
方法为模型获取查询构建器的实例。
const users = await User
.query() // 👈现在可以访问所有查询构建器方法
.where('countryCode', 'IN')
.orWhereNull('countryCode')
要获取单行,你可以使用 .first
方法和 firstOrFail
方法。
const users = await User
.query()
.where('countryCode', 'IN')
.orWhereNull('countryCode')
.first() // 👈 添加 `LIMIT 1` 子句
更新#
使用模型执行更新的标准方法是查找记录,然后将其更新 / 保存到数据库中。
const user = await User.findOrFail(1)
user.lastLoginAt = DateTime.local() // Luxon dateTime is used
await user.save()
此外,你可以使用 merge
方法一次定义所有属性,然后调用 save
方法。
await user
.merge({ lastLoginAt: DateTime.local() })
.save()
为什么不直接使用更新查询呢?#
更新记录的另一种方法是使用查询构建器手动执行更新。例如:
await User
.query()
.where('id', 1)
.update({ lastLoginAt: new Date() })
但是,直接更新记录不会触发任何模型钩子,也不会自动更新时间戳。
我们建议不要过多强调额外的 select
查询,除非每秒处理数百万次更新并经常脱离模型的功能。
删除#
像 update
操作一样,先从数据库中获取它再删除。例如:
const user = await User.findOrFail(1)
await user.delete()
同样,为了使钩子起作用,Lucid 首先需要模型的实例。如果你决定直接使用查询构建器,那么模型将不会触发任何钩子。
但是,直接查询构建器方法有助于执行批量删除。
await User.query().where('isVerified', false).delete()
幂等方法#
模型提供了许多有用的方法来简化记录的创建,方法是首先在数据库中找到,并仅在记录不存在时运行创建 / 更新查询。
firstOrCreate#
在数据库中搜索记录或创建新记录 (仅在查找失败时)。.
在以下示例中,当初始查找失败时,我们尝试使用电子邮件搜索用户,但同时保留 email
和 password
。换言之,searchPayload
和 savePayload
在 create 调用期间合并。
import User from 'App/Models/User'
const searchPayload = { email: 'virk@adonisjs.com' }
const savePayload = { password: 'secret' }
await User.firstOrCreate(searchPayload, savePayload)
fetchOrCreateMany#
fetchOrCreateMany
类似于 firstOrCreate
方法,但是你可以创建多个行。该方法需要一个唯一的键来查找重复的行和一个一直存在的对象数组 (如果在数据库中不存在)。
import User from 'App/Models/User'
const usersToCreate = [
{
email: 'foo@example.com',
},
{
email: 'bar@example.com',
},
{
email: 'baz@example.com',
}
]
await User.fetchOrCreateMany('email', usersToCreate)
updateOrCreate#
updateOrCreate
要么创建新记录,要么更新现有记录。与 firstOrCreate
方法一样,你需要定义搜索负载和要插入 / 更新的属性。
import User from 'App/Models/User'
const searchPayload = { email: 'virk@adonisjs.com' }
const persistancePayload = { password: 'secret' }
await User.updateOrCreate(searchPayload, persistancePayload)
updateOrCreateMany#
updateOrCreateMany
方法允许通过避免重复条目来同步行。该方法需要一个唯一的键来查找重复的行和一个要保持 / 更新的对象数组。
import User from 'App/Models/User'
const usersToCreate = [
{
email: 'foo@example.com',
},
{
email: 'bar@example.com',
},
{
email: 'baz@example.com',
}
]
await User.updateOrCreateMany('email', usersToCreate)
扩展阅读#
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。