Prisma 详尽教程

Prisma 是一个现代化的数据库工具链,包含 Prisma Client(自动生成的类型安全查询构建器)、Prisma Migrate(迁移系统)和 Prisma Studio(数据库 GUI)。本教程将全面介绍 Prisma 的各个方面。

目录

  1. Prisma 核心概念
  2. 安装与设置
  3. 数据建模
  4. Prisma Client 使用
  5. 高级查询
  6. 关系处理
  7. Prisma Migrate
  8. Prisma Studio
  9. 与框架集成
  10. 最佳实践

Prisma 核心概念

1. Prisma Schema

定义数据模型的核心文件,位于 prisma/schema.prisma,包含:

  • 数据源 (数据库连接)
  • 生成器 (客户端生成配置)
  • 数据模型定义

2. Prisma Client

自动生成的类型安全数据库客户端,提供:

  • CRUD 操作
  • 类型安全查询
  • 关系查询

3. Prisma Migrate

数据库迁移工具,特点:

  • 基于声明的数据模型
  • 生成迁移历史
  • 保持开发与生产环境同步

安装与设置

1. 初始化项目

npm init -y
npm install prisma typescript ts-node @types/node --save-dev
npx tsc --init
npx prisma init

2. 配置数据库连接

编辑 prisma/schema.prisma: prisma

datasource db {
  provider = "postgresql" // 或 mysql, sqlite, sqlserver, mongodb
  url      = env("DATABASE_URL")
}

.env 文件中设置连接字符串: env

DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"

3. 安装 Prisma Client

npm install @prisma/client

数据建模

1. 基本模型定义

prisma

model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  name      String?
  createdAt DateTime @default(now())
  posts     Post[]
}

2. 字段类型与修饰符

  • 标量类型: Int, String, Boolean, DateTime, Float, Decimal, Json, Bytes
  • 修饰符:
    • @id - 主键
    • @unique - 唯一约束
    • @default - 默认值
    • @updatedAt - 自动更新时间戳

3. 枚举类型

prisma

enum Role {
  USER
  ADMIN
}
model User {
  id   Int    @id @default(autoincrement())
  role Role   @default(USER)
}

Prisma Client 使用

1. 初始化客户端

import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
  // 查询操作将在这里进行
}
main()
  .catch(e => {
    throw e
  })
  .finally(async () => {
    await prisma.$disconnect()
  })

2. CRUD 操作

创建记录:

const user = await prisma.user.create({
  data: {
    name: 'Alice',
    email: 'alice@prisma.io',
  },
})

查询单个记录:

const user = await prisma.user.findUnique({
  where: {
    email: 'alice@prisma.io',
  },
})

更新记录:

const updatedUser = await prisma.user.update({
  where: {
    email: 'alice@prisma.io',
  },
  data: {
    name: 'Alicia',
  },
})

删除记录:

const deletedUser = await prisma.user.delete({
  where: {
    email: 'alice@prisma.io',
  },
})

高级查询

1. 过滤与分页

const users = await prisma.user.findMany({
  where: {
    name: {
      contains: 'alice',
    },
  },
  skip: 10,   // 跳过前10条
  take: 5,    // 取5条
  orderBy: {
    createdAt: 'desc',
  },
})

2. 聚合查询

const aggregations = await prisma.user.aggregate({
  _count: {
    _all: true,
  },
  _avg: {
    age: true,
  },
  where: {
    role: 'ADMIN',
  },
})

3. 原生 SQL 查询

const result = await prisma.$queryRaw`
  SELECT * FROM User WHERE email = ${email}
`

关系处理

1. 一对一关系

prisma

model Profile {
  id     Int     @id @default(autoincrement())
  bio    String?
  user   User    @relation(fields: [userId], references: [id])
  userId Int     @unique
}
model User {
  id      Int      @id @default(autoincrement())
  profile Profile?
}

2. 一对多关系

prisma

model Post {
  id       Int     @id @default(autoincrement())
  title    String
  author   User    @relation(fields: [authorId], references: [id])
  authorId Int
}
model User {
  id    Int     @id @default(autoincrement())
  posts Post[]
}

3. 多对多关系

prisma

model Post {
  id         Int         @id @default(autoincrement())
  categories Category[]
}
model Category {
  id    Int    @id @default(autoincrement())
  posts Post[]
}

4. 级联操作

prisma

model User {
  id      Int      @id @default(autoincrement())
  posts   Post[]
}
model Post {
  id       Int     @id @default(autoincrement())
  author   User    @relation(fields: [authorId], references: [id], onDelete: Cascade)
  authorId Int
}

Prisma Migrate

1. 创建迁移

npx prisma migrate dev --name init

2. 应用迁移到生产环境

npx prisma migrate deploy

3. 重置数据库

npx prisma migrate reset

4. 迁移历史

npx prisma migrate status

Prisma Studio

启动可视化数据库管理工具:

npx prisma studio

与框架集成

1. 与 Express 集成

import express from 'express'
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
const app = express()
app.get('/users', async (req, res) => {
  const users = await prisma.user.findMany()
  res.json(users)
})
app.listen(3000, () => 
  console.log('Server running on port 3000'))

2. 与 Next.js 集成

import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
export async function getServerSideProps() {
  const users = await prisma.user.findMany()
  return { props: { users } }
}

3. 全局 Prisma 客户端实例

为了避免多个 Prisma 客户端实例,可以创建共享实例:

import { PrismaClient } from '@prisma/client'
const globalForPrisma = global as unknown as { prisma: PrismaClient }
export const prisma = globalForPrisma.prisma || new PrismaClient()
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma

最佳实践

  1. 环境分离:
    • 为开发、测试和生产环境使用不同的数据库
    • 使用 .env 文件管理连接字符串
  2. 错误处理:
    try {
      await prisma.user.create({ data: { email: 'existing@email.com' } })
    } catch (e) {
      if (e instanceof Prisma.PrismaClientKnownRequestError) {
        if (e.code === 'P2002') {
          console.log('唯一约束冲突')
        }
      }
      throw e
    }
    
  3. 性能优化:
    • 使用 select 只查询需要的字段
    • 合理使用事务
    • 批量操作时使用 createManyupdateMany
  4. 日志记录:
    const prisma = new PrismaClient({
      log: ['query', 'info', 'warn', 'error'],
    })
    
  5. 连接池管理:
    const prisma = new PrismaClient({
      datasources: {
        db: {
          url: 'postgresql://user:password@localhost:5432/mydb?connection_limit=5',
        },
      },
    })
    

总结

Prisma 提供了现代化的数据库访问体验,通过本教程您已经学习了:

  • 数据建模与迁移
  • 基本的 CRUD 操作
  • 高级查询技巧
  • 关系处理
  • 与各种框架的集成
  • 生产环境最佳实践 Prisma 的类型安全特性和直观的 API 设计可以显著提高开发效率,同时减少数据库相关的错误。随着项目的增长,Prisma 的迁移系统和查询优化功能也能帮助维护数据库的健康状态。









results matching ""

    No results matching ""