Prisma ORM 第四章 表之间关系的建立和删除

server/2024/10/23 17:20:54/

1. content

在 Prisma 中,connect 是一个用于建立关系的选项,主要用于在创建或更新记录时将现有记录关联起来。connect 允许你在不重新创建相关记录的情况下,将它们链接到当前记录。这在处理多对多关系或多对一关系时特别有用。

1. connect 的作用

connect 通常用于以下几种情况:

  • 创建记录时建立关系:在创建新记录时,将其与已存在的记录关联。
  • 更新记录时建立关系:在更新现有记录时,将其与已存在的记录关联。

2. 一对多关系中的content

假设你有一个 User 模型和一个 Post 模型,其中 User 可以有多篇 Post。

  • 模型定义
prisma">model User {id    Int     @id @default(autoincrement())name  Stringemail String  @uniqueage   Intposts Post[]
}model Post {id      Int     @id @default(autoincrement())title   Stringcontent Stringauthor  User    @relation(fields: [authorId], references: [id])authorId Int
}
  1. 创建用户并关联帖子
const user = await prisma.user.create({data: {name: 'John Doe',email: 'john.doe@example.com',age: 25,posts: {connect: [{ id: 1 }, { id: 2 }], // 关联已存在的帖子},},
});console.log(user);
  1. 更新记录时使用 connect
    假设你已经有一个用户,现在想为该用户添加新的帖子。
  • 更新用户并关联帖子
const user = await prisma.user.update({where: {id: 1,},data: {email: "newEmail@"posts: {connect: [{ id: 3 }], // 关联新的帖子},},
});console.log(user);

3. 多对多关系中的 connect

假设你有一个 User 模型和一个 Role 模型,其中 User 可以有多个 Role,Role 也可以属于多个 User。

  • 模型定义
prisma">model User {id    Int     @id @default(autoincrement())name  Stringemail String  @uniqueage   Introles Role[]  @relation("UserRoles")
}model Role {id    Int     @id @default(autoincrement())name  Stringusers User[]  @relation("UserRoles")
}
  1. 创建用户并关联角色
const user = await prisma.user.create({data: {name: 'John Doe',email: 'john.doe@example.com',age: 25,roles: {connect: [{ id: 1 }, { id: 2 }], // 关联已存在的角色},},
});console.log(user);
  1. 更新用户并关联角色
const user = await prisma.user.update({where: {id: 1,},data: {roles: {connect: [{ id: 3 },{ id: 4 }], // 关联新的角色},},
});console.log(user);

2. connectOrCreate

作用: 用于在创建或更新记录时,将现有记录关联起来,或者在关联记录不存在时创建它。

1. 基本概念

connectOrCreate 选项允许你在关联记录不存在时创建它,并将其与当前记录关联。它接受一个数组,每个元素都是一个对象,包含 where 和 create 两个属性:

  • where:用于查找现有记录的条件。如果找到匹配的记录,则将其关联。
  • create:如果 where 条件没有找到匹配的记录,则使用 create 中提供的数据创建新记录,并将其关联。

2. 示例

假设你有一个 User 模型和一个 Role 模型,其中 User 可以有多个 Role,Role 也可以属于多个 User。

  • 模型定义
prisma">model User {id    Int     @id @default(autoincrement())name  Stringemail String  @uniqueage   Introles Role[]  @relation("UserRoles")
}model Role {id    Int     @id @default(autoincrement())name  String  @uniqueusers User[]  @relation("UserRoles")
}

3. 创建用户并连接或创建角色

const user = await prisma.user.create({data: {name: 'John Doe',email: 'john.doe@example.com',age: 25,roles: {connectOrCreate: [{where: { name: 'Admin' },create: { name: 'Admin' },},{where: { name: 'Editor' },create: { name: 'Editor' },},],},},
});console.log(user);
  • 在这个示例中:

    • 如果 Role 表中已经存在 name 为 Admin 的记录,则将其与新创建的用户关联。
    • 如果 Role 表中不存在 name 为 Admin 的记录,则创建一个新的 Role 记录,并将其与新创建的用户关联。
    • 同样的逻辑适用于 Editor 角色。

4. 更新用户并连接或创建角色

const user = await prisma.user.update({where: {id: 1,},data: {roles: {connectOrCreate: [{where: { name: 'Moderator' },create: { name: 'Moderator' },},],},},
});console.log(user);
  • 在这个示例中:

    • 如果 Role 表中已经存在 name 为 Moderator 的记录,则将其与用户 ID 为 1 的用户关联。
    • 如果 Role 表中不存在 name 为 Moderator 的记录,则创建一个新的 Role 记录,并将其与用户 ID 为 1 的用户关联。

5. 处理唯一约束

connectOrCreate 特别适合处理具有唯一约束的字段。例如,Role 模型中的 name 字段被标记为 @unique,这意味着每个角色名称必须是唯一的。connectOrCreate 确保不会创建重复的角色记录。

6. 错误处理

如果 where 条件不唯一,connectOrCreate 会抛出错误。因此,确保 where 条件能够唯一标识记录。

  • 示例:处理错误
try {const user = await prisma.user.create({data: {name: 'John Doe',email: 'john.doe@example.com',age: 25,roles: {connectOrCreate: [{where: { name: 'Admin' },create: { name: 'Admin' },},{where: { name: 'Admin' }, // 重复的 where 条件create: { name: 'Admin' },},],},},});console.log(user);
} catch (error) {console.error('Error:', error.message);
}

在这个示例中,由于 where 条件重复,connectOrCreate 会抛出错误。

3. disconnect

作用: 用于断开现有记录之间的关系。

1. 基本概念

disconnect 选项允许你在更新记录时断开与现有记录的关联。它接受一个数组,每个元素都是一个对象,包含用于查找要断开关联的记录的条件。

2. 示例

假设你有一个 User 模型和一个 Role 模型,其中 User 可以有多个 Role,Role 也可以属于多个 User。

  • 模型定义
prisma">model User {id    Int     @id @default(autoincrement())name  Stringemail String  @uniqueage   Introles Role[]  @relation("UserRoles")
}model Role {id    Int     @id @default(autoincrement())name  String  @uniqueusers User[]  @relation("UserRoles")
}

3. 断开用户与角色的关联

const user = await prisma.user.update({where: {id: 1,},data: {roles: {disconnect: [{ id: 2 }], // 断开与角色 ID 为 2 的关联},},
});console.log(user);

在这个示例中:

  • where 条件指定了要更新的用户(ID 为 1)。
  • data 对象中的 roles 字段使用了 disconnect 选项,传入了一个数组,数组中的每个对象都包含一个 id 属性,用于指定要断开关联的角色。

4. 断开多个关联

你可以在 disconnect 数组中指定多个对象,以断开多个关联。

const user = await prisma.user.update({where: {id: 1,},data: {roles: {disconnect: [{ id: 2 }, { id: 3 }], // 断开与角色 ID 为 2 和 3 的关联},},
});console.log(user);

在这个示例中:

  • disconnect 数组中包含了两个对象,分别指定了要断开关联的角色 ID 为 2 和 3。

5. 使用其他条件断开关联

除了使用 id,你还可以使用其他唯一字段来断开关联。

const user = await prisma.user.update({where: {id: 1,},data: {roles: {disconnect: [{ name: 'Editor' }], // 断开与角色名称为 'Editor' 的关联},},
});console.log(user);

在这个示例中:

  • disconnect 数组中的对象使用了 name 字段来指定要断开关联的角色。

6. 断开所有关联

如果你想断开用户与所有角色的关联,可以使用 set 选项并将值设置为空数组。

const user = await prisma.user.update({where: {id: 1,},data: {roles: {set: [], // 断开与所有角色的关联},},
});console.log(user);

在这个示例中:

  • set 选项将 roles 设置为空数组,从而断开用户与所有角色的关联。

7. 错误处理

如果 disconnect 中的条件不匹配任何记录,Prisma 不会抛出错误,而是简单地忽略该条件。因此,你需要确保条件是正确的,以避免意外的行为。

try {const user = await prisma.user.update({where: {id: 1,},data: {roles: {disconnect: [{ id: 999 }], // 不存在的角色 ID},},});console.log(user);
} catch (error) {console.error('Error:', error.message);
}

在这个示例中:

  • disconnect 中的 id: 999 不存在,Prisma 会忽略该条件,不会抛出错误。

http://www.ppmy.cn/server/134216.html

相关文章

NeRF三维重建—神经辐射场Neural Radiance Field(二)体渲染相关

NeRF三维重建—神经辐射场Neural Radiance Field(二)体渲染相关 粒子采集部分 粒子采集的部分我们可以理解为,在已知粒子的情况下,对图片进行渲染的一个正向的过程。 空间坐标(x,y,z)发射的光线通过相机模型成为图片上…

2024软考网络工程师笔记 - 第10章.组网技术

文章目录 交换机基础1️⃣交换机分类2️⃣其他分类方式3️⃣级联和堆叠4️⃣堆叠优劣势5️⃣交换机性能参数 🕑路由器基础1️⃣路由器接口2️⃣交换机路由器管理方式2️⃣交换机路由器管理方式 交换机基础 1️⃣交换机分类 1.根据交换方式分 存储转发式交换(Store…

【p2p、分布式,区块链笔记 UPNP】: 简单服务发现协议 SSDP

在设备加入网络,UPnP发现协议允许设备向控制点广告它的服务。它使用向一个标准地址和端口多址传送发现消息来实现。控制点在此端口上侦听是否有新服务加入系统。为了通知所有设备,一个设备为每个其上的嵌入设备和服务发送一系列相应的发现消息。每个消息…

【Hive】4-HiveSQL 数据操控语言(DML)

HiveSQL 数据操控语言(DML) load加载数据 语法 -- 语法规则 LOAD DATA [LOCAL] INPATH filepath [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1val1, partcol2val2...)] -- 语法规则(Hive 3.0及以后) LOAD DATA [LOC…

中级职称和副高级职称,退休工资一年相差多少?

2014年,社会养老保险政策进行了统一并轨,但设立了10年的过渡期。过渡期结束后,每名事业单位员工都必须缴纳养老保险,原则上是“多缴多得,长缴长待,不缴不得”。 那么,事业单位副高和中级职称退…

后台管理员登录实现--系统篇

我的小系统后台原来就有一个上传图片的功能还夹带个删除图片的功能,还嵌到了一个菜单里面。之前效果如下 那么现在为了加大安全力度,想增加一个登录页面。通过登录再到这个页面。看着貌似很简单,但是听我细细说来,要新增些什么东西…

Idea 2023.2.7构建SpringCloud多模块项目

Idea 2023.2.7构建SpringCloud多模块项目 本文介绍如何使用idea 2023.2.7构建基于SpringCloud alibaba微服务项目,基于Nacos注册中心。 环境准备: JDK版本:jdk17 SpringBoot:3.3.4 SpringCloud:2023.0.3 Nacos服务端:2.4.3 1、创建父工程&a…

1971. 寻找图中是否存在路径

有一个具有 n 个顶点的 双向 图,其中每个顶点标记从 0 到 n - 1(包含 0 和 n - 1)。图中的边用一个二维整数数组 edges 表示,其中 edges[i] [ui, vi] 表示顶点 ui 和顶点 vi 之间的双向边。 每个顶点对由 最多一条 边连接&#x…