Prisma官方文档(英文):https://www.prisma.io/docs/getting-started
Prisma中文文档:https://prisma.yoga/reference
安装
npm install prisma --save-dev
npm install @prisma/client --save
初始化
在项目的根目录中运行以下命令来初始化Prisma
prisma init
这个命令做了两件事:
- 在项目中创建一个
prisma
目录,里面包含一个schema.prisma
文件。这个文件用来定义数据源和数据模型 - 创建了一个
.env
文件,用于定义环境变量
连接数据库
系统环境变量或者.env文件
# 格式
DATABASE_URL="<数据库类型>://<数据库用户名>:<数据库密码>@<服务器地址>:<端口号>/<数据库名字>?schema=public"
# 例子
DATABASE_URL="mysql://username:password@localhost:3306/database_name?schema=public"
prisma/schema.prisma
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
在上面的示例中,我们使用 mysql
作为数据源的提供程序,并指定了 MariaDB 数据库的连接信息。
创建数据模型(model)
- 从现有的数据库中
内省
模型
这将根据数据库的表结构自动生成数据model并写到prisma/schema.prisma文件中prisma db pull
- 编辑schema.prisma文件来定义数据库模型。例如,以下是一个示例模型
运行以下命令创建一个新的表,会在prisma/migrations目录生成本次的迁移文件# 定义了一个名为user的数据模型,它包含id、name、email三个字段 model user { id Int @id @default(autoincrement()) name String email String @unique }
prisma migrate dev
--name
可选,代表本次迁移的名称,比如:init
查看数据库
prisma studio
使用Prisma
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
export default function HomePage({ users }) {
return (
<div>
<h1>Users</h1>
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
)
}
export async function getServerSideProps() {
const users = await prisma.user.findMany()
return {
props: {
users,
},
}
}
如何定义数据模型
https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference
关联查询
- 定义数据model
comment表中的enum Role { ADMIN USER VISITOR } model user { id Int @id @default(autoincrement()) nickname String email String @unique password String avatar String? role Role @default(USER) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") comments comment[] @relation("CommentUser") commentReplies comment[] @relation("CommentReplyUser") } model comment { id Int @id @default(autoincrement()) parentId Int? @map("parent_id") userId Int @map("user_id") replyUserId Int? @map("reply_user_id") articleId String @map("article_id") content String createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") user user @relation(name: "CommentUser", fields: [userId], references: [id]) replyUser user? @relation(name: "CommentReplyUser", fields: [replyUserId], references: [id]) parent comment? @relation(name: "CommentChildren", fields: [parentId], references: [id]) children comment[] @relation(name: "CommentChildren") }
user
字段起到了关键作用,目的是将comment表中的userId字段与user表中的id字段进行关联,同时要在user表中加入comments comment[]
- 插入数据
// 关联的字段不能用正常的方式插入数据,具体方式参照这个代码 const options = { articleId, content, user: { connect: { id: userId, }, } } if (parentId) { options.parent = { connect: { id: parentId, }, } } if (replyUserId) { options.replyUser = { connect: { id: replyUserId, }, } } prisma.comment.create({ data: { ...options }, })
- 查询数据
只关联某些字段const comments = await prisma.comment.findMany({ where: {parentId: null, articleId}, // 找到 parentId 为 null 的主评论 take: count, skip: (page - 1) * count, orderBy: {createdAt: 'desc'}, // 按照创建时间倒序排序 include: { children: { include: { user: true, replyUser: true } }, user: true, replyUser: true } });
const comments = await prisma.comment.findMany({ where: {parentId: null, articleId}, // 找到 parentId 为 null 的主评论 take: count, skip: (page - 1) * count, orderBy: {createdAt: 'desc'}, // 按照创建时间倒序排序 include: { children: { include: { user: { select: { id: true, nickname: true } }, replyUser: { select: { id: true, nickname: true } } } }, user: { select: { id: true, nickname: true } }, replyUser: { select: { id: true, nickname: true } } } });