CRUD
此页面描述了如何使用生成的 Prisma Client API 执行 CRUD 操作。CRUD 是一个首字母缩略词,代表
有关所有可用方法的完整列表,请参阅客户端 API 参考文档。
示例模式和提供程序
所有示例都基于以下 Prisma 模式
展开以查看模式 (schema.prisma
)
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "dart run orm"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
age Int?
role Role @default(USER)
posts Post[]
Profile Profile?
country String?
city String?
profileViews Int @default(0)
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
categories Category[]
views Int @default(0)
likes Int @default(0)
tags String[] @default([])
}
model Profile {
id Int @id @default(autoincrement())
bio String?
user User @relation(fields: [userId], references: [id])
userId Int @unique
}
model Category {
id Int @id @default(autoincrement())
name String @unique
posts Post[]
}
enum Role {
USER
ADMIN
}
展开以查看提供程序 (prisma.dart
)
import 'dart:async';
import 'prisma/generated_dart_client/client.dart';
/// Create a new instance of PrismaClient
final _client = PrismaClient();
/// Provide a PrismaClient instance to a function.
///
/// Wrapped in a function to ensure that the instance is diconnected
/// after the function is done.
FutureOr<T> providePrisma<T>(
FutureOr<T> Function(PrismaClient prisma) main) async {
try {
return await main(_client);
} finally {
await _client.$disconnect();
}
}
创建
创建单个记录
以下查询创建 (create
) User
模型的单个记录,其中包含两个字段
final user = await prisma.user.create(
data: PrismaUnion.$1(UserCreateInput(
email: "seven@odroe.com",
name: PrismaUnion.$1("Seven Du"),
)),
);
显示查询结果
{id: 1, email: seven@odroe.com, name: Seven Du, role: USER}
用户的 id
由数据库自动生成。
创建多个记录
以下 createMany
查询创建多个用户并跳过任何重复项(email
必须唯一)
final affectedRows = await prisma.user.createMany(
data: PrismaUnion.$2([
UserCreateManyInput(
name: PrismaUnion.$1("Bob1"), email: "bob@prisma.pub"),
UserCreateManyInput(
name: PrismaUnion.$1("Bob2"), email: "bob@prisma.pub"),
UserCreateManyInput(
name: PrismaUnion.$1("Yewande"), email: "yewande@prisma.pub"),
UserCreateManyInput(
name: PrismaUnion.$1("Ange"), email: "ange@prisma.pub"),
]),
skipDuplicates: true, // Skip 'Bob2'
);
显示查询结果
{count: 3}
提示
使用 **MongoDB** 和 **SQL Server** 时不支持 skipDuplicates
。
创建记录并连接或创建相关记录
有关同时创建记录和一个或多个相关记录的信息,请参阅相关查询 -> 嵌套写入。
读取
按 ID 或唯一字段获取记录
以下查询按 ID 或唯一字段返回单个记录 (findUnique
)
final user = await prisma.user.findUnique(
where: UserWhereUniqueInput(id: 1),
);
final user = await prisma.user.findUnique(
where: UserWhereUniqueInput(email: "seven@odroe.com"),
);
获取所有记录
以下 findMany
查询返回所有 User
记录
final users = await prisma.user.findMany();
您还可以对结果进行分页。
获取与特定条件匹配的第一条记录
以下 findFirst
查询返回最近创建的 User
,该用户至少有一篇 post
的点赞数超过 100
- 按降序 ID(最大值优先)对用户进行排序 - 最大的 ID 是最近创建的用户。
- 过滤至少有一篇点赞数超过 100 的帖子的用户。
final user = await prisma.user.findFirst(
where: UserWhereInput(
posts: PostListRelationFilter(
some: PostWhereInput(
likes: PrismaUnion.$1(
IntFilter(gt: PrismaUnion.$1(100)),
),
),
),
),
orderBy: PrismaUnion.$2(
UserOrderByWithRelationInput(id: SortOrder.desc),
),
);
获取过滤后的记录列表
Prisma Dart 客户端支持对记录字段和相关字段进行过滤。
按单个字段值过滤
以下查询返回所有电子邮件以 "odroe.com" 结尾的 User
记录
final users = await prisma.user.findMany(
where: UserWhereInput(
email: PrismaUnion.$1(
StringFilter(endsWith: PrismaUnion.$1('@odroe.com')),
),
),
);
按多个字段值过滤
以下查询使用运算符组合返回名称以 S
开头或角色为 ADMIN
的用户
final users = await prisma.user.findMany(
where: UserWhereInput(
OR: [
UserWhereInput(
name: PrismaUnion.$1(
StringNullableFilter(startsWith: PrismaUnion.$1("S")),
),
),
UserWhereInput(
role: PrismaUnion.$2(Role.admin),
),
],
),
);
按相关记录字段值过滤
以下查询返回电子邮件域名是 odroe.com
且至少有一篇未发布的帖子 (somo
) 的用户
final users = await prisma.user.findMany(
where: UserWhereInput(
email: PrismaUnion.$1(
StringFilter(endsWith: PrismaUnion.$1("@odroe.com")),
),
posts: PostListRelationFilter(
some: PostWhereInput(
published: PrismaUnion.$2(false),
),
),
),
);
有关根据相关字段值进行过滤的更多示例,请参阅使用关系。
选择字段子集
以下 findUnique
查询使用 select
返回特定 User
记录的 name
和 email
字段
final user = await prisma.user.findUnique(
where: UserWhereUniqueInput(email: "seven@odroe.com"),
select: UserSelect(
name: true,
email: true,
),
);
有关包含关系的更多信息,请参阅
选择相关记录字段的子集
以下查询使用嵌套选择返回
User
的email
字段- 每个
Post
的likes
字段
final user = await prisma.user.findUnique(
where: UserWhereUniqueInput(email: "seven@odroe.com"),
select: UserSelect(
email: true,
posts: PrismaUnion.$2(
UserPostsArgs(
select: PostSelect(likes: true),
),
),
),
);
包含相关记录
以下查询返回所有 ADMIN
用户并在结果中包含每个用户的帖子
final users = await prisma.user.findMany(
where: UserWhereInput(
role: PrismaUnion.$2(Role.admin),
),
include: UserInclude(
posts: PrismaUnion.$1(true),
),
);
有关包含关系的更多信息,请参阅选择字段 -> 嵌套读取。
更新
更新单个记录
以下查询使用 update
通过 email
查找并更新单个 User
记录
final updatedUser = await prisma.user.update(
where: UserWhereUniqueInput(email: "seven@odroe.com"),
data: PrismaUnion.$2(
UserUncheckedUpdateInput(
name: PrismaUnion.$1("Seven Odroe"),
),
),
);
显示查询结果
{id: 1, email: seven@odroe.com, name: Seven Odroe, role: USER}
更新多个记录
以下查询使用 updateMany
将所有电子邮件中包含 odroe.com
的 User 记录的 role
更新为 ADMIN
final affectedRows = await prisma.user.updateMany(
where: UserWhereInput(
email: PrismaUnion.$1(
StringFilter(endsWith: PrismaUnion.$1("@odroe.com")),
),
),
data: PrismaUnion.$1(
UserUpdateManyMutationInput(
role: PrismaUnion.$1(Role.admin),
),
),
);
显示查询结果
{ count: 1 }
更新或创建记录
以下查询使用 upsert
更新具有特定 email
地址的 User
记录,如果该 User
记录不存在,则创建该记录
final user = await prisma.user.upsert(
where: UserWhereUniqueInput(email: "medz@prisma.pub"),
create: PrismaUnion.$1(UserCreateInput(
email: "medz@prisma.pub",
name: PrismaUnion.$1("Seven at GitHub username"),
)),
update: PrismaUnion.$1(
UserUpdateInput(
name: PrismaUnion.$1("Seven at GitHub username"),
),
),
);
从 4.6.0 版开始,Prisma 在可能的情况下使用数据库本机 SQL 命令执行 upsert。
查找或创建
您可以使用 Dart extension
创建 findOrCreate
方法
extension UserFindOrCreate on UserDelegate {
ActionClient<User> findOrCreate({
required UserWhereUniqueInput where,
required UserCreateInput data,
// ... More fields can be added here
}) {
return upsert(
where: where,
create: PrismaUnion.$1(data),
// Create a empty update input, make sure the update input is not null
update: PrismaUnion.$2(UserUncheckedUpdateInput()),
);
}
}
现在您可以使用 findOrCreate
方法
final user = await prisma.user.findOrCreate(
where: UserWhereUniqueInput(email: "seven@odroe.com"),
data: UserCreateInput(
email: "seven@odroe.com",
name: PrismaUnion.$1("Seven Du"),
),
);
警告
Prisma 没有 findOrCreate 查询。您可以使用 upsert 作为解决方法。要使 upsert 的行为类似于 findOrCreate 方法,请向 upsert 提供一个空的更新参数。
更新数字字段
使用原子数字运算来更新数字字段 **基于其当前值** - 例如,increment
或 multiply
。以下查询将 views
和 likes
字段增加 1
final affectedRows = await prisma.post.updateMany(
data: PrismaUnion.$1(
PostUpdateManyMutationInput(
views: PrismaUnion.$2(
IntFieldUpdateOperationsInput(increment: 1),
),
likes: PrismaUnion.$2(
IntFieldUpdateOperationsInput(increment: 1),
),
),
),
);
删除
删除单个记录
以下查询使用 delete
删除单个 User
记录
final deletedUser = await prisma.user.delete(
where: UserWhereUniqueInput(
email: "bob@prusma.pub",
),
);
尝试删除一个或多个帖子的用户会导致错误,因为每个帖子都需要一个作者 - 请参阅 👉 级联删除
删除多个记录
以下查询使用 deleteMany
删除所有 Use
记录,其中 email
域名是 odroe.com
final affectedRows = await prisma.user.deleteMany(
where: UserWhereInput(
email: PrismaUnion.$1(
StringFilter(
endsWith: PrismaUnion.$1('@odroe.com'),
),
),
),
);
尝试删除一个或多个帖子的用户会导致错误,因为每个帖子都需要一个作者 - 请参阅 👉 级联删除
删除所有记录
以下查询使用 deleteMany
删除所有 User
记录
final affectedRows = await prisma.user.deleteMany();
请注意,如果用户有任何相关记录(例如帖子),此查询将失败。在这种情况下,您需要先删除相关记录。
级联删除(删除相关记录)
以下查询使用 delete
删除单个 User
记录
final deletedUser = await prisma.user.delete(
where: UserWhereUniqueInput(
email: "bob@prusma.pub",
),
);
但是,示例模式在 Post
和 User
之间包含一个 **必需的关系**,这意味着您不能删除包含帖子的用户
The change you are trying to make would violate the required relation 'PostToUser' between the `Post` and `User` models.
要解决此错误,您可以
- 使关系可选prisma
model Post { id Int @id @default(autoincrement()) author User? @relation(fields: [authorId], references: [id]) authorId Int? author User @relation(fields: [authorId], references: [id]) authorId Int }
- 在删除用户之前将帖子的作者更改为其他用户。
- 在事务中使用两个单独的查询删除用户及其所有帖子(所有查询都必须成功)dart
await prisma.$transaction((prisma) async { await prisma.post.deleteMany(); await prisma.user.deleteMany(); });
不可序列化的查询值
Prisma Client Dart 支持以下不可序列化的查询值
final data = await prisma.user.findMany().unserialized();
所有模型操作都支持 unserialized
方法。