全栈开发个人博客05:Prisma操作数据库

127 阅读2分钟

Prisma 是一个现代化的数据库工具链,它提供了一个类型安全的 ORM(对象关系映射),使得开发者能够轻松地与数据库进行交互。通过 Prisma,可以自动生成类型化的数据库查询,减少了手写 SQL 的需求,是构建高效、可扩展的数据库应用的理想选择。

1. Vercel Postgres 免费数据库

Vercel 平台推出了数据库存储服务,对于免费用户,每月的数据库操作 10 万次,存储 10 G,写个小小的个人站点足够了。

Vercel 平台上 Storage tab下新建一个 Prisma Postgres 数据服务,在.env文件粘贴Vercel的数据库地址DATABASE_URL="************",本地的数据库操作都会直接影响远程存储。

2. Prisma 项目初始化

Prisma 是一个基于 Nodejs 和 TypeScript 的 ORM,它可以帮助开发者以 更快的开发速度 和 更少的错误 来 管理数据库。

具体步骤参考官方指南How to use Prisma ORM with Next.js,我生成的客户端目录与官网不同,其他内容都一致

  1. 安装及初始化配置

安装依赖

npm install prisma tsx --save-dev
npm install @prisma/extension-accelerate @prisma/client

初始化配置

npx prisma init --db --output ../src/generated/prisma

这步操作会做下列事项:

  • 一个包含 schema.prisma 文件的 prisma 目录。
  • 一个 Prisma Postgres 数据库。
  • 项目根目录下包含 DATABASE_URL 的 .env 文件。
  • 定义生成的 Prisma Client 输出目录为 src/generated/prisma。
  1. 定义模型配置

修改我们需要的博客模型,id 使用cuid()生成,会比纯数字自增更合适,起码不容易被恶意爬虫抓数据

// prisma/schema.prisma

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
  output   = "../src/generated/prisma"
}

generator pothos {
  provider = "prisma-pothos-types"
}

model User {
  id        String    @id @default(cuid())
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
  email     String    @unique
  image     String?
  nickname  String    @default("")
  role      Role      @default(USER)
  bookmarks Link[]
  posts     Post[]
}

enum Role {
  USER
  ADMIN
}

model Post {
  id          String    @id @default(cuid())
  title       String
  summary     String    @default("")
  content     String
  createdAt   DateTime  @default(now())
  updatedAt   DateTime  @updatedAt
  createdBy   User      @relation(fields: [createdById], references: [id])
  createdById String
}


  1. 配置Prisma客户端

npx prisma migrate dev --name init

这一步操作会在本地建立 User 表 和 Post 表,生成 prisma 客户端文件

后期模型有修改都需要执行 npx prisma migrate dev --name xxxx,同步修改表信息

查看本地数据库页面 npx prisma studio,保存修改会同步到远程存储

3. 使用Prisma操作数据库

  1. 设置prisma客户端

前一步生成的客户端文件,在这里直接导进来

//src/lib/prisma.ts
import { PrismaClient } from '../generated/prisma'
import { withAccelerate } from '@prisma/extension-accelerate'

const globalForPrisma = global as unknown as {
  prisma: PrismaClient
}

const prisma =
  globalForPrisma.prisma || new PrismaClient().$extends(withAccelerate())

if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma

export default prisma
  1. 查文章列表
import prisma from '@/lib/prisma'
const posts = await prisma.post.findMany()
  1. 新建文章
import prisma from '@/lib/prisma'
await prisma.post.create({
  data: {
    title,
    content,
  },
})
  1. 更新文章
import prisma from '@/lib/prisma'
const post = await prisma.post.update({
  where: { id },
  data: { title, summary, content },
})
  1. 删除文章
import prisma from '@/lib/prisma'
await prisma.post.delete({
  where: { id },
})