简单实现了一个后端,把会员注册功能先做了出来,但奇怪的是却一直没再往下手。
大概是虽然用过 Prisma 和 PostgreSQL,但只是读着别人的文章被动地跟着做,结果没真正学会,这似乎就是问题所在。
所以决定这次自己从头实现一遍。
1. 安装 PostgreSQL
首先用 homebrew 安装 postgresql。
如果是 Windows,可以先装 choco,再通过它来安装,会比较简单。
然后通过 services start 设置成自动启动。
# 如果是 MacBook
brew install postgresql
brew services start postgresql输入下面的命令,如果能正常连接就说明安装完成了。
postgreSQL 是服务器-客户端结构,所以 postgre 服务器必须在运行中,才能连接到数据库。
psql postgres
现在来设置用户和数据库。
我把用户名设成 testuser,密码也设成 testuser。
CREATE USER testuser WITH PASSWORD 'testuser';
\du
用户总是建不出来,检查了一下才发现,命令末尾一定要加分号,命令才算结束。
然后再创建一个 database。
CREATE DATABASE testdb;再用 \l 或 \list 查看数据库列表。

这里上面那 3 个 db 是默认创建的。
删掉可能会出问题,最好保持不动。
2. 安装 Prisma
现在来安装 Prisma。
我新建了一个名为 prismaTest 的文件夹。
用 npm 也可以,不过我这里是用 yarn 来初始化的。
yarn然后安装 Prisma。
用 npx 命令执行 Prisma 的初始化设置。
运行 prisma init 后,会在某个文件夹下生成 Prisma 配置文件。
顺便说一下,npx 是一种命令行工具,可以在不全局安装 npm 包的情况下直接运行它们。
yarn add prisma
npx prisma init3. 设置 PostgreSQL 连接
接下来进入 prisma/schema.prisma.env,修改环境配置。
把文件内部的设置改成如下所示即可。
DATABASE_URL="postgresql://아이디:비밀번호@localhost:5432/데이터베이스이름?schema=public"4. 设置 schema.prisma
现在来设置数据库的 schema。
默认情况下,schema 内容如下:
generator client {
provider = "prisma-client-js"
output = "../generated/prisma" <-- 이 줄 삭제할 것!
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}接下来可以自由修改。
问题在于,需要先稍微学一下 schema 的写法。
比如说,假设有下面这样的 schema:
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}➡️ model User { ... } 是数据库的表名。
➡️ id Int @id @default(autoincrement())
这个字段是主键,数字会按 1、2、3… 这样自动递增。
元素 | 含义 |
|---|---|
| 字段(列,column)名 |
| 数据类型 = 整型 |
| 该字段是 Primary Key |
| 默认值为自增数字 |
➡️ email String @unique
email 的值必须唯一,不能有两个以上用户使用同一个邮箱。
元素 | 含义 |
|---|---|
| 字段名 |
| 字符串类型 |
| 不可重复(Unique 约束) |
➡️ name String?
name 可以有,也可以是 null(没有)。
元素
含义
name字段名
String?字符串类型,其中
?表示 nullable(可为 null)
总结一下 Prisma 的装饰器如下:
装饰器 | 含义 |
|---|---|
| 指定主键 |
| 设置默认值 |
| 唯一值约束 |
| 关系设置(外键、关联表) |
| 指定在实际数据库中的列名 |
| 该字段 可为 null(值可以不存在) |
| 数组(例如: |
| 当字段类型为 datetime 时,更新数据时自动刷新为当前日期 |
5. 执行迁移
为了把模型反映到 DB 上,需要进行迁移。
最后面的名称可以随意取。
npx prisma migrate dev --name testMyDB
## 在 --name 后面输入迁移名称6. Prisma Client 使用示例
现在写一个简单的服务器,在后端测试一下 CRUD。
服务器将用 Express 来写。
yarn add @prisma/client express先用上面的命令安装依赖。
创建 index.js 文件,并按下面这样输入代码。
然后在终端运行 node index.js,服务器就会启动。
const express = require('express');
const { PrismaClient } = require('@prisma/client');
const app = express();
const prisma = new PrismaClient();
app.use(express.json());
const port = 3001;
app.get("/", (req, res)=> {
const body = req.params;
res.send("test");
});
app.get('/users', async (req, res) => {
const users = await prisma.User.findMany();
console.log(users);
res.send(`<div>${users.map((user) => {
return `<name:$>email : ${user.email} / name:${user.name}</p><br>`
}).join("")}</div>`);
});
app.get('/input', async (req, res) => {
const { email, name } = req.query;
const result = await prisma.User.create({data:{email : email, name: name}})
console.log(email, name);
res.send(`<h1>${email
}</h1>
<h2>${name}</h2>
`);
})
app.listen(port, () => {
console.log("listen http://localhost:3001")
});Prisma 的用法是 prisma.表名.命令 这样的形式。
服务器已经在运行,现在通过 query string 传入邮箱和姓名试试看。
http://localhost:3001/input?email=testur@email.com&name=힘센캥거루输入之后,在 /users 里查看,可以看到数据被正确输出。

同样的方法也可以进行修改和删除。
先添加下面这段代码:
...
app.get("/delete", async (req, res) => {
const { email } = req.query;
const result = await prisma.User.delete({where : {email: email}});
console.log(email);
res.send(`<h1>${email} 삭제 성공</h1>`)
})
...
然后像下面这样发请求,就会删除对应数据。
http://localhost:3001/delete?email=testur@email.com修改也不难。
在 where 里传入要匹配的数据,在 data 字段里写需要变更的内容即可。
...
app.get("/edit", async (req, res) => {
const { email, name } = req.query;
const result = await prisma.User.update({where : {email: email},
data : {name : name}
});
console.log(email, name);
res.send(`<h1>${email} 이름 수정 성공</h1>`)
})
...然后加上 query string 再去查看,就能看到名字已经按下面这样被修改了。

7. 在 nextjs 中使用
要在 nextjs 中方便地使用 Prisma,需要做一些事前准备。
我在 src/lib 文件夹里新建了 prisma.ts 文件。
写上负责处理所有和 user 相关输入输出的代码。
import { PrismaClient } from "@prisma/client";
const globalWithPrisma = global as typeof globalThis & {
prisma: PrismaClient;
};
let prisma: PrismaClient;
// 非开发模式时,每次都新建连接
if (process.env.NODE_ENV === "production") {
prisma = new PrismaClient();
} else {
if (!globalWithPrisma.prisma) {
globalWithPrisma.prisma = new PrismaClient();
}
// 开发模式时,为防止内存泄漏,复用已有连接
prisma = globalWithPrisma.prisma;
}
export default prisma;
这样之后,我在 /src/db 目录下定义了用于管理 user 的函数。
import { dbUserObject } from "@/types/allTypes";
import prisma from "@/lib/prisma";
export async function createUser(data: dbUserObject) {
try {
const user = await prisma.user.create({
data: {
...
email : data.user.email as string,
...
}
});
return user; // 返回创建好的用户
} catch (error) {
console.error('Error create user', error);
throw error;
}
}
export async function getAllUsers() {
try {
const users = await prisma.user.findMany();
return users;
} catch (error) {
console.error('Error fetching users:', error);
throw error;
}
}
// Read - 查询特定用户
export async function getUserByEmail(email: string) {
try {
const user = await prisma.user.findUnique({
where: { email },
});
return user;
} catch (error) {
console.error('Error fetching user:', error);
throw error;
}
}
export async function updateUser(email: string, data: Partial<Omit<dbUserObject, 'email'>>) {
try {
const updatedUser = await prisma.user.update({
where: { email },
data: {
nickName : data.user?.nickName,
...
},
});
return updatedUser;
} catch (error) {
console.error('Error updating user:', error);
throw error;
}
}
export async function deleteUser(email: string) {
try {
const deletedUser = await prisma.user.delete({
where: { email },
});
return deletedUser;
} catch (error) {
console.error('Error deleting user:', error);
throw error;
}
}
8. 后记
以前总觉得后端本身很难,但有这些工具帮忙之后就轻松多了。
虽然有很多不同的库,但其中 Prisma 看起来是最直观也最好用的。
之后想用它来给自己的网站,以及项目都试着做一做。
댓글을 불러오는 중...