【Next.js 入门教程系列】05-数据库

news2024/11/20 21:24:24

原文链接

CSDN 的排版/样式可能有问题,去我的博客查看原文系列吧,觉得有用的话, 给我的库点个star,关注一下吧

上一篇【Next.js 入门教程系列】04-构造 API

数据库

本篇包括以下内容:

  • Setting up Prisma
  • Defining data models
  • Creating migrations
  • Performing CRUD operations

Prisma​

本章代码链接

Prisma 是一款 ORM(Object–relational mapping) 软件。使用 npm i prisma 命令安装 Prisma

安装好后,使用 npx prisma init 初始化 Prisma。init 好之后,会有 /prisma/schema.prisma 和 .env 两个文件

可以根据自己使用的数据库来修改一下,在Prisma Connection String查看设置文档。笔者使用的是 MySQL,修改如下所示。

DATABASE_URL="mysql://USER:PASSWORD@HOST:PORT/DATABASE"
datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

修改完成后建议把 .env 加入到 .gitignore 中,避免自己账号密码流出

定义 model​

本章代码链接

在 /prisma/schema.prisma 可以添加 model ,相当于数据库表,其格式如下,具体内容可以参考Prisma Model

model User {
  id        Int     @id @default(autoincrement())
  email     String  @unique
  name      String
  followers Int     @default(0)
  isActive  Boolean @default(true)
}

在写好之后可以使用 npx prisma format 来格式化,会自动进行对齐等操作

同步到数据库​

本章代码链接

在创建好 model 之后,可以通过下面的命令来同步到数据库

  • 关系型数据库
  • 非关系型数据库
<!-- 关系型数据库 -->
npx prisma migrate dev

<!-- 非关系型数据库 -->
npx prisma db push

 使用该命令后,会在prisma/migrations/20240224061001_initial 中自动生成 .sql 文件,并会自动创建对应 Database。相应的,每次修改 /prisma/schema.prisma 中的 model 之后,运行该指令,都会生成对应的修改 sql 文件

创建 Prisma Client​

本章代码链接

在Prisma Creating Client这一节,给出了如何创建一个全局的 PrismaClient 供我们使用,其具体代码如下,我们只需要 CV 一次,后面直接使用即可。注意需要放到 prisma/client.ts 中

Prisma Client

# prisma/client.ts

import { PrismaClient } from "@prisma/client";

const prismaClientSingleton = () => {
  return new PrismaClient();
};

declare global {
  var prisma: undefined | ReturnType<typeof prismaClientSingleton>;
}

const prisma = globalThis.prisma ?? prismaClientSingleton();

export default prisma;

if (process.env.NODE_ENV !== "production") globalThis.prisma = prisma;

获取数据​

本章代码链接

需要获取数据时,导入全局的 prismaClient 对象,用 .findUnique 或 .findMany 方法来获取数据。

  # api/users/route.tsx

  // findMany 方法
  import schema from "./schema";
  // 导入 prisma
+ import prisma from "@/prisma/client";

- export function GET(request: NextRequest) {
-   return NextResponse.json([
-     { id: 1, name: "Castamere" },
-     { id: 2, name: "Today_Red" },
-   ]);

+ export async function GET(request: NextRequest) {
+   const users = await prisma.user.findMany();
+   return NextResponse.json(users);
  }

同样我们可以将之前动态路由中的参数([id])作为筛选项来获取数据,只需要调用 findUnique 方法即可(在 GET 方法中)。在Prisma Filtering and Sorting可以找到 prisma 相关的筛选与排序语法

  api/users/[id]/route.tsx

  // findUnique 方法
  import { NextRequest, NextResponse } from "next/server";
  import schema from "../schema";
  // 导入 prisma
+ import prisma from "@/prisma/client";

  export async function GET(
    request: NextRequest,
  // 这里提到前文一个错误,slug中的id,比如 user/1,这个1被读取时是String而非number,使用时需要手动 parseInt
-   { params: { id } }: { params: { id: number } }
+   { params: { id } }: { params: { id: string } }
  ) {
+   const user = await prisma.user.findUnique({ where: { id: parseInt(id) } });
    if (!user)
      return NextResponse.json({ error: "User not found" }, { status: 404 });
    return NextResponse.json({ user });
  }

上传数据​

本章代码链接

上传数据直接调用 prisma.user.create() 方法即可,用在 POST 方法中

# api/users/route.tsx

export async function POST(request: NextRequest) {
  const body = await request.json();
  const validation = schema.safeParse(body);
  if (!validation.success)
    return NextResponse.json(validation.error.errors, { status: 400 });
  // 检查是否已有重复
  const check = await prisma.user.findUnique({
    where: { email: body.email },
  });
  if (check)
    return NextResponse.json({ error: "User already exists" }, { status: 400 });
  // 上传数据
  const user = await prisma.user.create({
    data: {
      name: body.name,
      email: body.email,
    },
  });
  return NextResponse.json(user, { status: 201 });
}

修改数据​

本章代码链接

修改数据则调用 prisma.user.update(),注意用在 PUT 方法中

  # api/users/[id]/route.tsx

  // 直接补全之前函数中空的部分
  export async function PUT(
    request: NextRequest,
    { params: { id } }: { params: { id: string } }
  ) {
    // Validate the request body
    const body = await request.json();
    const validation = schema.safeParse(body);
    // If invalid, return 400
    if (!validation.success)
      return NextResponse.json(validation.error.errors, { status: 400 });
    // Fetch the user
+   const user = await prisma.user.findUnique({
+     where: { id: parseInt(id) },
+   });
    // If does not exist, return 404
    if (!user)
      return NextResponse.json({ error: "User not found" }, { status: 404 });
    // Update the user
+   const updatedUser = await prisma.user.update({
+     where: { id: user.id },
+     data: {
+       name: body.name,
+       email: body.email,
+     },
+   });
    // Return the updated user
    return NextResponse.json(updatedUser);
  }

删除数据​

本章代码链接

删除数据调用 prisma.user.delete(),注意用在 DELETE 方法中

  api/users/[id]/route.tsx

  // 直接补全之前函数中空的部分
  export async function DELETE(
    request: NextRequest,
    { params: { id } }: { params: { id: string } }
  ) {
    // Fetch user from db
+   const user = await prisma.user.findUnique({
+     where: { id: parseInt(id) },
+   });
    // If does not exist, return 404
    if (!user)
      return NextResponse.json({ error: "User not found" }, { status: 404 });
    // Delete the user
+   await prisma.user.delete({
+     where: { id: user.id },
+   });
    // Return 200
    return NextResponse.json({});
  }

 CSDN 的排版/样式可能有问题,去我的博客查看原文系列吧,觉得有用的话, 给我的库点个star,关注一下吧

下一篇讲文件上传

下一篇【Next.js 入门教程系列】06-上传文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2213872.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pinia学习笔记(1.0)

首先贴出官网地址&#xff1a;开始 | Pinia pinia作为Vue3项目中常用的状态管理工具&#xff0c;正逐渐取代vuex&#xff0c;现从0到1自己搭建pinia仓库。 首先&#xff0c;安装pinia&#xff0c;使用包管理器工具&#xff08;npm,pnpm,yarn,Bun等都可以&#xff09; 安装成…

QGIS如何在正射影像中获得绘制线段的长度信息||QGIS如何获取绘制点的经纬度(如何生成WKT属性)并且导出为CSV文件

QGIS如何在正射影像中获得绘制线段的长度信息 前置条件&#xff1a; 导入正射影像和绘制完需要计算长度的绘制线段后 1.检查菜单栏是否有数据处理&#xff08;processing&#xff09;按键&#xff0c;如果没有的话请根据以下链接打开processing工具箱&#xff1a;https://bl…

微服务架构 --- Nacos的项目实战操作

目录 一.什么是Nacos&#xff1f; 二.什么是注册中心&#xff1f; 1.注册中心的定义&#xff1a; 2.为什么需要使用注册中心&#xff1f; 3.注册中心原理&#xff1a; 三.Nacos的使用&#xff1a; 1.安装与启动Nacos&#xff1a; 2.集成 Nacos 服务注册与发现&#xff…

邀你一起共建谷歌封号申诉共享库

大家好&#xff0c;我是牢鹅&#xff01;相信很多老粉是通过谷歌封号的三篇文章《聊聊「谷歌8.3」账号封禁解析与应对思路 》和《聊聊谷歌「高风险」封号问题解析与应对思路》、《聊聊这半年来&#xff0c;谷歌为何频繁封号&#xff1f;》关注牢鹅的&#xff0c;在这将近半年的…

架构设计笔记-13-层次式架构设计理论与实践

目录 知识要点 综合知识 案例分析 1.SSM框架 2.MVC模式&#xff0c;XML 3.MVC架构脆弱性 4.容器技术的优势 5.对象关系映射ORM技术 知识要点 一般来说&#xff0c;架构可以分为表现层、中间层和持久层三个层次。 表现层&#xff1a;表现层主要负责接收用户的请求&…

【论文翻译】TITAN:用于交通流量预测的异构专家混合模型

题目A TIME SERIES IS WORTH FIVE EXPERTS: HETEROGENEOUS MIXTURE OF EXPERTS FOR TRAFFIC FLOW PREDICTION论文链接https://arxiv.org/pdf/2409.17440源码地址https://github.com/sqlcow/TITAN&#xff08;作者说论文被接受后&#xff0c;代码将更新&#xff09; 摘要 准确的…

API项目4:开发SDK

面临另一个问题 作为开发者&#xff0c;每次调用接口都需要自己生成时间戳&#xff0c;编写签名算法&#xff0c;生成随机数等等&#xff0c;这些都是相当繁琐的工作。 因此&#xff0c;要想办法让开发者能够以最简单的方式调用接口。开发者只需要关心传递哪些参数以及他们的…

如何通过计算巢在阿里云一键部署FlowiseAI

什么是FlowiseAI FlowiseAI 是一个开源的低代码开发工具&#xff0c;专为开发者构建定制的语言学习模型&#xff08;LLM&#xff09;应用而设计。 通过其拖放式界面&#xff0c;用户可以轻松创建和管理AI驱动的交互式应用&#xff0c;如聊天机器人和数据分析工具。 它基于Lang…

网站分享 | 六个插件搜索下载网站

网站分享&#xff1a; 今天分享几个搜索插件的网站。 &#x1f527; Chrome Web Store —— 官方插件库&#xff0c;选择最多 谷歌官方的 Chrome 插件商店&#xff0c;拥有丰富的插件供你选择。无论你是办公党、学生党&#xff0c;还是娱乐爱好者&#xff0c;这里都能找到提…

第 4 章:Vue 中的 ajax

1. 解决开发环境 Ajax 跨域问题 vue脚手架配置代理 原理图&#xff1a; 1.1 方法一 在vue.config.js中添加如下配置&#xff1a; devServer:{proxy:"http://localhost:5000" // 这个5000 是请求目标的端口号 }说明&#xff1a; 优点&#xff1a;配置简单&…

杰理AC632N---发射功率问题

AC632N的发射功率SDK默认0dbm左右&#xff0c;在实际做产品时&#xff0c;如果使用SDK默认的发射功率&#xff0c;则测试到的发射功率达不到规格书上面的8dbm. 查看代码流程发现SDK中修改发射功率的文职如下&#xff1a; 修改到level 10 则是最大功率8dbm , 使用频谱仪可以测得…

OpenAI 最新发布的 o1 模型在 ARC-AGI-Pub 数据集上的测试结果与分析

在过去的24小时内&#xff0c;我们有幸获得了 OpenAI 新发布的 o1-preview 和 o1-mini 模型的使用权限。这些模型经过特别训练&#xff0c;旨在模拟推理过程&#xff0c;并在给出最终答案之前给予更多时间生成和修正推理步骤。 成百上千的人都在问&#xff0c;o1 在 ARC 奖项上…

linux线程 | 线程的控制(一)

前言&#xff1a;本节内容为线程的控制。在本篇文章中&#xff0c; 博主不仅将会带友友们认识接口&#xff0c; 使用接口。 而且也会剖析底层&#xff0c;带领友友们理解线程的底层原理。 相信友友们学完本节内容&#xff0c; 一定会对线程的控制有一个很好的把握。 那么&#…

Gin框架官方文档详解03:HTML渲染

官方文档&#xff1a;https://gin-gonic.com/zh-cn/docs/ 注&#xff1a;强烈建议没用过Gin的读者先阅读第一节&#xff1a;第一个Gin应用。 目录 一、简单渲染二、使用不同目录下名称相同的模板三、自定义模板渲染器四、自定义分隔符五、自定义模板函数六、总结 一、简单渲染 …

数通--5

一、链路聚合 背景&#xff1a;带宽不够&#xff0c;加线&#xff0c;但是stp判断是环路&#xff0c;阻塞&#xff0c;等于没加线。通过链路聚合解决&#xff08;如果我把千兆换成万兆&#xff0c;老子有钱任性的话&#xff0c;没得说&#xff09; 现在我要的不是备份而是带宽…

电能表预付费系统-标准传输规范(STS)(4)

5.4 TokenCarrier 到 MeterApplicationProcess 的数据流 The flow of data from the TokenCarrier to the MeterApplicationProcess is shown in Figure 4.此数据流见图 4。 图 4 TokenCarrier 到 MeterApplicationProcess 的数据 The token entry process from the TokenCarr…

抢单超卖? 并发问题解决思路

1. 问题介绍 在用户抢单或者商品售卖的过程中&#xff0c;正常情况下是一人一件&#xff0c;但是当网络流量剧增时多个用户同时抢到一个商品应该如何分配&#xff1f;假设这样一个场景A商品库存是100个&#xff0c;但是秒杀的过程中&#xff0c;一共卖出去500个A商品。对于卖家…

AXI GPIO按键控制——ZYNQ学习笔记4

一、AXI GPIO接口简介 是什么&#xff1f;是PL部分的一个IP软核&#xff0c;实现通用输入输出接口的功能&#xff0c;并通过AXI协议实现与处理系统通信&#xff0c;方便控制与拓展GPIO接口。 AXI GPIO IP 核为 AXI 接口提供了一个通用的输入/输出接口。 与 PS 端的 GPIO 不同&…

【YOLO系列】YOLO11原理和深入解析——待完善

文章目录 前言一、主要新增特性二、主要改进2.1 C3K2网络结构2.2 C2PSA网络结构2.3 Head部分 三、对比与性能优势四、X-AnyLabeling4.1 目标检测&#xff1a;4.2 实例分割&#xff1a;4.3 图像分类&#xff1a;4.4 姿态估计&#xff1a;4.5 旋转目标检测&#xff1a; 五、总结 …

Vue+Vant实现7天日历展示,并在切换日期时实时变换

效果图&#xff1a; 主要使用 moment.js 插件完成 HTML部分 <div class"day-content"><div class"day-content-t"><div>{{ monthVal }}</div><div click"onCalendar()">更多>></div></div><…