Skip to content
On this page

Prisma CRUD 操作

Prisma Client 提供了直观的 API 来执行数据库的创建(Create)、读取(Read)、更新(Update)和删除(Delete)操作。本指南将详细介绍各种 CRUD 操作的使用方法。

创建操作 (Create)

基本创建

typescript
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()

// 创建单个记录
async function createUser() {
  const user = await prisma.user.create({
    data: {
      email: 'alice@prisma.io',
      name: 'Alice',
    },
  })
  console.log(user)
}

创建带关联数据的记录

typescript
// 创建用户及其相关帖子
async function createUserWithPosts() {
  const user = await prisma.user.create({
    data: {
      email: 'bob@prisma.io',
      name: 'Bob',
      posts: {
        create: [
          {
            title: 'First Post',
            content: 'Hello World',
          },
          {
            title: 'Second Post',
            content: 'More content',
          },
        ],
      },
    },
    include: {
      posts: true, // 包含创建的帖子
    },
  })
  return user
}

创建多个记录

typescript
// 创建多个用户
async function createMultipleUsers() {
  const users = await prisma.user.createMany({
    data: [
      { email: 'user1@example.com', name: 'User 1' },
      { email: 'user2@example.com', name: 'User 2' },
      { email: 'user3@example.com', name: 'User 3' },
    ],
    skipDuplicates: true, // 跳过重复项(基于唯一字段)
  })
  console.log(`${users.count} users created`)
}

嵌套创建

typescript
// 创建用户、帖子和评论
async function createNestedData() {
  const result = await prisma.user.create({
    data: {
      email: 'charlie@prisma.io',
      name: 'Charlie',
      posts: {
        create: {
          title: 'My Post',
          content: 'Post content',
          comments: {
            create: [
              {
                content: 'Great post!',
                author: {
                  connect: { email: 'alice@prisma.io' }, // 连接到现有用户
                },
              },
            ],
          },
        },
      },
    },
    include: {
      posts: {
        include: {
          comments: {
            include: {
              author: true,
            },
          },
        },
      },
    },
  })
  return result
}

读取操作 (Read)

查找单个记录

typescript
// 根据唯一字段查找
async function findUserById() {
  const user = await prisma.user.findUnique({
    where: {
      id: 1,
    },
  })
  return user // 如果不存在则返回 null
}

// 根据多个唯一字段查找
async function findUserByEmail() {
  const user = await prisma.user.findUnique({
    where: {
      email: 'alice@prisma.io',
    },
    select: {
      id: true,
      name: true,
      email: true,
    },
  })
  return user
}

// 查找或抛出错误
async function findUserOrThrow() {
  try {
    const user = await prisma.user.findUniqueOrThrow({
      where: {
        id: 999, // 假设不存在
      },
    })
    return user
  } catch (error) {
    console.log('User not found')
    return null
  }
}

查找多个记录

typescript
// 查找所有记录
async function findAllUsers() {
  const users = await prisma.user.findMany()
  return users
}

// 带条件的查找
async function findActiveUsers() {
  const users = await prisma.user.findMany({
    where: {
      email: {
        contains: 'prisma.io', // 包含特定字符串
      },
      name: {
        not: null, // 名字不为空
      },
    },
  })
  return users
}

// 分页查询
async function getUsersWithPagination() {
  const users = await prisma.user.findMany({
    skip: 10, // 跳过前 10 条
    take: 5,  // 获取 5 条记录
    orderBy: {
      createdAt: 'desc', // 按创建时间降序
    },
  })
  return users
}

高级查询条件

typescript
// 复杂查询条件
async function findUsersWithComplexFilter() {
  const users = await prisma.user.findMany({
    where: {
      AND: [
        {
          email: {
            endsWith: 'prisma.io',
          },
        },
        {
          OR: [
            {
              name: {
                contains: 'Alice',
              },
            },
            {
              createdAt: {
                gte: new Date('2023-01-01'), // 大于等于
              },
            },
          ],
        },
      ],
    },
    include: {
      posts: {
        where: {
          published: true, // 只包含已发布的帖子
        },
      },
    },
  })
  return users
}

聚合查询

typescript
// 计数
async function countUsers() {
  const userCount = await prisma.user.count({
    where: {
      email: {
        contains: 'prisma.io',
      },
    },
  })
  return userCount
}

// 其他聚合操作
async function aggregateData() {
  const result = await prisma.post.aggregate({
    where: {
      published: true,
    },
    _count: {
      _all: true, // 计数所有记录
      title: true, // 计数非空标题
    },
    _sum: {
      viewCount: true, // 求和
    },
    _avg: {
      rating: true, // 平均值
    },
    _min: {
      createdAt: true, // 最小值
    },
    _max: {
      createdAt: true, // 最大值
    },
  })
  return result
}

更新操作 (Update)

基本更新

typescript
// 更新单个记录
async function updateUser() {
  const user = await prisma.user.update({
    where: {
      id: 1,
    },
    data: {
      name: 'Updated Name',
      email: 'updated@example.com',
    },
  })
  return user
}

// 更新或创建
async function upsertUser() {
  const user = await prisma.user.upsert({
    where: {
      email: 'newuser@prisma.io',
    },
    update: {
      name: 'Existing User Updated',
    },
    create: {
      email: 'newuser@prisma.io',
      name: 'New User',
    },
  })
  return user
}

批量更新

typescript
// 更新多个记录
async function updateMultipleUsers() {
  const result = await prisma.user.updateMany({
    where: {
      email: {
        contains: 'old-domain.com',
      },
    },
    data: {
      email: { // 这会将所有匹配的记录的邮箱设置为相同值
        // 实际使用中通常不会这样,而是通过其他方式更新
      },
    },
  })
  console.log(`${result.count} users updated`)
}

嵌套更新

typescript
// 更新用户及其关联数据
async function updateUserWithPosts() {
  const user = await prisma.user.update({
    where: {
      id: 1,
    },
    data: {
      name: 'Updated Name',
      posts: {
        update: {
          where: { id: 1 },
          data: {
            title: 'Updated Title',
            published: true,
          },
        },
        create: {
          title: 'New Post',
          content: 'New post content',
        },
      },
    },
    include: {
      posts: true,
    },
  })
  return user
}

关系更新

typescript
// 更新关系
async function updateRelations() {
  const post = await prisma.post.update({
    where: { id: 1 },
    data: {
      author: {
        connect: { id: 2 }, // 连接到用户 ID 为 2 的用户
      },
    },
    include: {
      author: true,
    },
  })
  return post
}

// 断开关系
async function disconnectRelation() {
  const post = await prisma.post.update({
    where: { id: 1 },
    data: {
      author: {
        disconnect: true, // 断开与作者的关系
      },
      tags: {
        disconnect: { id: 1 }, // 断开特定标签的连接
      },
    },
  })
  return post
}

删除操作 (Delete)

基本删除

typescript
// 删除单个记录
async function deleteUser() {
  const user = await prisma.user.delete({
    where: {
      id: 1,
    },
  })
  return user
}

// 删除或返回 null
async function deleteUserSafely() {
  try {
    const user = await prisma.user.delete({
      where: {
        id: 999, // 不存在的 ID
      },
    })
    return user
  } catch (error) {
    console.log('User not found, nothing was deleted')
    return null
  }
}

批量删除

typescript
// 删除多个记录
async function deleteMultipleUsers() {
  const result = await prisma.user.deleteMany({
    where: {
      email: {
        contains: 'spam.com',
      },
    },
  })
  console.log(`${result.count} users deleted`)
  return result
}

级联删除

typescript
// 删除用户及其相关帖子(如果数据库支持级联删除)
async function deleteUserWithPosts() {
  const result = await prisma.user.delete({
    where: {
      id: 1,
    },
    include: {
      posts: true, // 包含要删除的帖子
    },
  })
  return result
}

高级 CRUD 操作

原生 SQL 查询

typescript
// 原生查询(查询)
async function rawSelectQuery() {
  const users = await prisma.$queryRaw`
    SELECT id, email, name 
    FROM User 
    WHERE email LIKE ${'%prisma.io%'}
  `
  return users
}

// 原生执行(修改)
async function rawExecuteQuery() {
  const result = await prisma.$executeRaw`
    UPDATE User 
    SET name = CONCAT(name, ' (Updated)')
    WHERE email LIKE ${'%prisma.io%'}
  `
  console.log(`${result} users updated`)
  return result
}

事务操作

typescript
// 使用事务确保数据一致性
async function createUserInTransaction() {
  const result = await prisma.$transaction(async (tx) => {
    // 创建用户
    const user = await tx.user.create({
      data: {
        email: 'transaction@example.com',
        name: 'Transaction User',
      },
    })

    // 创建用户的个人资料
    const profile = await tx.profile.create({
      data: {
        bio: 'This user was created in a transaction',
        userId: user.id,
      },
    })

    return { user, profile }
  })

  return result
}

// 使用事务数组形式
async function createMultipleInTransaction() {
  const [user, post] = await prisma.$transaction([
    prisma.user.create({
      data: {
        email: 'multi@example.com',
        name: 'Multi Transaction User',
      },
    }),
    prisma.post.create({
      data: {
        title: 'First Post',
        authorId: 1, // 假设用户存在
      },
    }),
  ])

  return { user, post }
}

条件操作

typescript
// 条件创建(如果不存在则创建)
async function conditionalCreate() {
  try {
    const user = await prisma.user.create({
      data: {
        email: 'unique@example.com',
        name: 'Unique User',
      },
    })
    return { user, created: true }
  } catch (error: any) {
    if (error.code === 'P2002') { // 唯一约束违反
      const existingUser = await prisma.user.findUnique({
        where: { email: 'unique@example.com' },
      })
      return { user: existingUser, created: false }
    }
    throw error
  }
}

性能优化技巧

使用 select 优化查询

typescript
// 只获取需要的字段,提高性能
async function getUsersWithSelectedFields() {
  const users = await prisma.user.findMany({
    select: {
      id: true,
      name: true,
      email: true,
      // 不包含不需要的大字段
    },
  })
  return users
}

使用 include 控制关联数据

typescript
// 精确控制关联数据的获取
async function getUsersWithFilteredPosts() {
  const users = await prisma.user.findMany({
    include: {
      posts: {
        where: {
          published: true,
        },
        select: {
          id: true,
          title: true,
          createdAt: true,
        },
        orderBy: {
          createdAt: 'desc',
        },
        take: 5, // 只获取最近的 5 篇文章
      },
    },
  })
  return users
}

通过掌握这些 CRUD 操作,您可以有效地管理数据库中的数据,并根据应用需求执行各种数据操作任务。