下面给一个完整、能把核心心智串起来的示例。
#1. schema.prisma
datasource db {
provider = "postgresql"
}
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
createdAt DateTime @default(now())
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id])
createdAt DateTime @default(now())
}
model AuditLog {
id Int @id @default(autoincrement())
action String
entity String
entityId Int
createdAt DateTime @default(now())
}#2. 生成 Client
prisma generate#3. 业务代码:blog-demo.ts
import { PrismaClient } from "./generated/prisma";
const prisma = new PrismaClient();
async function main() {
// 1) 如果作者存在就更新,不存在就创建
const author = await prisma.user.upsert({
where: { email: "lin@city.dev" },
update: { name: "Lin" },
create: {
email: "lin@city.dev",
name: "Lin",
posts: {
create: [
{
title: "Prisma 不是魔法,是事务所",
content: "先把 schema 想清楚,再写业务。",
},
],
},
},
include: { posts: true },
});
console.log("作者及其文章:", author);
// 2) 查询已发布文章,并把作者信息一起带出来
const publishedPosts = await prisma.post.findMany({
where: { published: true },
select: {
id: true,
title: true,
createdAt: true,
author: {
select: {
id: true,
email: true,
name: true,
},
},
},
orderBy: { createdAt: "desc" },
});
console.log("已发布文章:", publishedPosts);
// 3) 用事务把“发布文章 + 写审计日志”打包
const postId = author.posts[0]?.id;
if (!postId) {
throw new Error("没有可发布的文章");
}
const publishedPost = await prisma.$transaction(async (tx) => {
const post = await tx.post.findUnique({
where: { id: postId },
select: { id: true, published: true },
});
if (!post) {
throw new Error("文章不存在");
}
if (post.published) {
return tx.post.findUnique({ where: { id: post.id } });
}
await tx.post.update({
where: { id: post.id },
data: { published: true },
});
await tx.auditLog.create({
data: {
action: "PUBLISH_POST",
entity: "Post",
entityId: post.id,
},
});
return tx.post.findUnique({
where: { id: post.id },
include: {
author: {
select: { id: true, email: true, name: true },
},
},
});
});
console.log("发布后的文章:", publishedPost);
}
main()
.catch((error) => {
console.error(error);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});这个示例一口气串起了:
schemamodelrelationprisma generateupsert- 关联读取
- 事务
- 审计记录
它最值得记住的不是代码本身,而是这条工作流:
先定义数据契约
▼
生成类型安全入口
▼
在业务代码里清晰表达查询与写入意图
▼
用事务保护关键业务边界