Prisma ORM 教程

学习使用 Prisma ORM 与 Neon PostgreSQL 数据库进行类型安全的数据库操作

什么是 Prisma ORM?

Prisma 是一个现代化的 TypeScript ORM,提供类型安全的数据库访问、 自动生成的查询构建器和强大的数据库迁移工具。它与 Neon PostgreSQL 完美集成。

类型安全

自动生成的 TypeScript 类型

数据库迁移

声明式数据库架构管理

直观的 API

简洁易读的查询语法

Prisma Schema 定义

Prisma Schema 是定义数据模型、数据库连接和生成器的配置文件。 它使用简洁的 DSL 语法描述数据库结构。

prisma/schema.prisma
// prisma/schema.prisma
generator client {
  provider = "prisma-client-js"
}

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

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

  @@map("users")
}

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  published Boolean  @default(false)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  authorId  Int
  author    User     @relation(fields: [authorId], references: [id], onDelete: Cascade)
  tags      Tag[]    @relation("PostTags")

  @@map("posts")
}

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

  @@map("profiles")
}

model Tag {
  id    Int    @id @default(autoincrement())
  name  String @unique
  posts Post[] @relation("PostTags")

  @@map("tags")
}

Prisma Client 设置

Prisma Client 是自动生成的类型安全数据库客户端。 在 Next.js 中需要特殊的设置来避免开发环境中的连接池问题。

lib/prisma.ts
// lib/prisma.ts
import { PrismaClient } from '@prisma/client';

const globalForPrisma = globalThis as unknown as {
  prisma: PrismaClient | undefined;
};

export const prisma = globalForPrisma.prisma ?? new PrismaClient();

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

Prisma Schema 可视化构建器

交互式构建和编辑 Prisma 数据模型,实时生成 Schema 代码

编辑 User 模型

idString@id @default(uuid())
emailString@unique
nameString?
postsPost[]
createdAtDateTime@default(now())
添加新字段

生成的 Schema

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

model Post {
  id String @id @default(uuid())
  title String 
  content String ?
  published Boolean @default(false)
  author User 
  authorId String 
}

Prisma 查询构建器

可视化构建复杂的 Prisma 查询,学习各种数据库操作的最佳实践

查询参数

生成的 Prisma 查询

await prisma.user.findMany({
});
操作描述: 获取多条记录

CRUD 操作演示

体验 Prisma 的增删改查操作,包括关联查询和复杂条件

用户列表 (User Model)

张三

zhangsan@example.com

3 篇文章

李四

lisi@example.com

1 篇文章

王五

wangwu@example.com

5 篇文章

文章管理 (Post Model)

Next.js 入门指南

作者: 张三 | 状态:已发布

TypeScript 最佳实践

作者: 张三 | 状态:已发布

Prisma ORM 深度解析

作者: 张三 | 状态:草稿

React 性能优化

作者: 李四 | 状态:已发布

数据库设计原则

作者: 王五 | 状态:已发布

Prisma 查询构建器

学习不同类型的 Prisma 查询及其返回结果

Prisma 查询代码:

const users = await prisma.user.findMany({
  include: {
    posts: {
      where: { published: true }
    }
  }
});

Next.js API 路由集成

在 Next.js 的 API 路由中使用 Prisma 进行数据库操作, 实现 RESTful API 端点。

API 路由示例
// app/api/users/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';

export async function GET() {
  try {
    const users = await prisma.user.findMany({
      include: {
        _count: {
          select: { posts: true }
        }
      }
    });

    return NextResponse.json(users);
  } catch (error) {
    return NextResponse.json(
      { error: '获取用户失败' },
      { status: 500 }
    );
  }
}

export async function POST(request: NextRequest) {
  try {
    const { name, email } = await request.json();

    const user = await prisma.user.create({
      data: { name, email }
    });

    return NextResponse.json(user, { status: 201 });
  } catch (error) {
    return NextResponse.json(
      { error: '创建用户失败' },
      { status: 500 }
    );
  }
}

// app/api/users/[id]/route.ts
export async function GET(
  request: NextRequest,
  { params }: { params: { id: string } }
) {
  try {
    const user = await prisma.user.findUnique({
      where: { id: parseInt(params.id) },
      include: {
        posts: true,
        profile: true
      }
    });

    if (!user) {
      return NextResponse.json(
        { error: '用户不存在' },
        { status: 404 }
      );
    }

    return NextResponse.json(user);
  } catch (error) {
    return NextResponse.json(
      { error: '获取用户失败' },
      { status: 500 }
    );
  }
}

数据库迁移和管理

Prisma 提供了强大的迁移工具来管理数据库架构变更。 以下是常用的 Prisma CLI 命令:

Prisma CLI 命令
// 初始化 Prisma
npx prisma init

// 生成 Prisma Client
npx prisma generate

// 创建和应用迁移
npx prisma migrate dev --name init

// 推送 schema 变更到数据库(用于原型开发)
npx prisma db push

// 打开 Prisma Studio(数据库可视化工具)
npx prisma studio

// 重置数据库
npx prisma migrate reset

// 从现有数据库生成 schema
npx prisma db pull

环境配置

.env 文件配置

.env
# Neon PostgreSQL 连接字符串
DATABASE_URL="postgresql://username:password@host:port/database?sslmode=require"

# 示例(请替换为你的实际连接信息)
DATABASE_URL="postgresql://username:password@hostname:port/database?sslmode=require"

package.json 脚本

package.json
{
  "scripts": {
    "db:generate": "prisma generate",
    "db:push": "prisma db push",
    "db:migrate": "prisma migrate dev",
    "db:studio": "prisma studio",
    "db:reset": "prisma migrate reset"
  }
}

Prisma 查询练习

尝试编写 Prisma 查询,体验类型安全的数据库操作:

Prisma 查询练习场

加载编辑器中...

Prisma 最佳实践

性能优化

  • 使用 select 和 include 精确控制查询字段
  • 合理使用索引和数据库约束
  • 使用分页避免大量数据查询
  • 利用连接池优化数据库连接

开发建议

  • 使用事务保证数据一致性
  • 定期备份和测试迁移
  • 使用 Prisma Studio 进行数据可视化
  • 充分利用 TypeScript 类型安全

准备好了吗?

现在你已经掌握了 Prisma ORM 的核心概念,让我们继续学习 Redis 缓存来优化应用性能。

学习 Redis 缓存