文章目录
Prisma 学习笔记
以下是 Next.js + MySQL + Prisma 从0到1的完整连接流程,包含数据库配置、API开发,全程基于TypeScript:
Prisma:通过数据模型定义自动生成数据库访问代码,支持TypeScript类型安全操作,减少手写SQL
1.创建Next.js项目
# 创建TypeScript项目
npx create-next-app@latest next-mysql-demo --typescript
cd next-mysql-demo
2.安装依赖(Prisma + MySQL驱动)
npm install prisma @types/node --save-dev
npm install @prisma/client @prisma/adapter-mariadb dotenv
prisma-Prisma CLI用于运行命令,如prisma init,prisma migrate,和prisma generate@prisma/client-用于查询数据库的Prisma客户端库@prisma/adapter-mariadb-将Prisma客户端连接到数据库的MySQL/MariaDB驱动程序适配器dotenv-从您的加载环境变量.env文件
3.配置ESM支持
更新tsconfig.json对于ESM兼容性:
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "node",
"target": "ES2023",
"strict": true,
"esModuleInterop": true,
"ignoreDeprecations": "6.0"
}
}
更新package.json要启用ESM:
{
"type": "module",
}
4.初始化Prisma
npx prisma init
这会生成:
prisma/schema.prisma:Prisma数据模型配置文件.env:环境变量文件(存储数据库连接信息)- 创建一个
prisma.config.tsPrisma配置文件
5.配置MySQL连接(.env + schema.prisma)
5.1 配置环境变量(.env)
打开 .env 文件,添加MySQL连接字符串:
# 格式:mysql://用户名:密码@主机:端口/数据库名
DATABASE_URL="mysql://root:你的密码@ip:端口号/数据库名"
DATABASE_USER="root"
DATABASE_PASSWORD="你的密码"
DATABASE_NAME="数据库名"
DATABASE_HOST="ip"
DATABASE_PORT=3306
- 替换
root为你的MySQL用户名 - 替换
你的密码为MySQL登录密码 - 确保
localhost:3306是你的MySQL主机和端口(默认本地为localhost:3306) next_mysql_db是要创建的数据库名(可自定义)
5.2 定义数据模型(prisma/schema.prisma)
打开 prisma/schema.prisma,编写业务数据模型(以“用户表”为例):
generator client {
provider = "prisma-client-js"
output = "../generated/prisma" // 修改prisma客户端包地址
}
datasource db {
provider = "mysql" // 标注数据库类型
}
// 定义用户模型
model User {
id Int @id @default(autoincrement())
name String
email String @unique
createdAt DateTime @default(now())
}
Prisma 7.0.0 引入了新的配置系统,将数据库连接信息从 schema.prisma 迁移到独立的 prisma.config.ts
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
// 配置 MySQL 连接 URL(读取 .env 中的环境变量)
url: env("DATABASE_URL") || process.env.DATABASE_URL || 'mysql://账号:密码#@ip:端口号/',
},
});
6.创建数据库表(Prisma迁移)
# 生成迁移文件(记录数据模型变更)
npx prisma migrate dev --name init
执行后,Prisma会自动在MySQL中创建表。
7.实例化Prisma客户端
现在您已经安装了所有依赖项,您可以实例化Prisma Client。您需要将Prisma ORM的驱动程序适配器的实例传递给PrismaClient构造函数:
// prisma/prisma.ts
import "dotenv/config";
import { PrismaMariaDb } from '@prisma/adapter-mariadb';
import { PrismaClient } from '../generated/prisma/client';
const adapter = new PrismaMariaDb({
host: process.env.DATABASE_HOST,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_NAME,
connectionLimit: 5
});
const prisma = new PrismaClient({ adapter });
export { prisma }
8.生成测试数据(可选,用于演示)
创建 prisma/seed.ts 脚本,填充测试数据:
// prisma/seed.ts
import { prisma } from './prisma'
async function main() {
// 生成近7天的漏洞趋势数据
const dates = Array.from({ length: 7 }, (_, i) => {
const d = new Date();
d.setDate(d.getDate() - i);
return d;
});
for (const date of dates) {
await prisma.vulnerability.create({
data: {
date,
critical: Math.floor(Math.random() * 20) + 5, // 5-25 之间随机
high: Math.floor(Math.random() * 30) + 10,
medium: Math.floor(Math.random() * 50) + 20,
low: Math.floor(Math.random() * 100) + 50,
},
});
}
// 生成风险榜单数据
const industries = ['金融', '医疗', '教育', '电商', '政务', '能源', '交通'];
for (let i = 0; i < 7; i++) {
await prisma.riskRank.create({
data: {
name: `${industries[i]}系统`,
riskLevel: Math.floor(Math.random() * 5) + 5, // 5-10 级
industry: industries[i],
value: Math.floor(Math.random() * 500) + 500, // 500-1000 风险值
},
});
}
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
在 package.json 中添加种子脚本配置:
{
"prisma": {
"seed": "ts-node prisma/seed.ts"
}
}
执行种子脚本:
npx tsx script.ts
9.创建Next.js API接口(pages/api)
9.1 获取所有用户(pages/api/users.ts)
import type { NextApiRequest, NextApiResponse } from 'next';
import { prisma } from '@/prisma/prisma';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method === 'GET') {
// 查询所有用户
const users = await prisma.user.findMany();
res.status(200).json(users);
} else {
res.status(405).json({ message: '仅支持GET请求' });
}
}
9.2 获取单个用户(pages/api/users/[id].ts)
import type { NextApiRequest, NextApiResponse } from 'next';
import { prisma } from '@/prisma/prisma';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const { id } = req.query;
if (typeof id !== 'string') {
res.status(400).json({ message: 'ID必须为字符串' });
return;
}
if (req.method === 'GET') {
// 根据ID查询用户
const user = await prisma.user.findUnique({
where: { id: parseInt(id) },
});
if (!user) {
res.status(404).json({ message: '用户不存在' });
return;
}
res.status(200).json(user);
} else {
res.status(405).json({ message: '仅支持GET请求' });
}
}
10.前端页面调用API(pages/index.tsx)
import { useEffect, useState } from 'react';
export default function Home() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
useEffect(() => {
// 调用API获取用户列表
fetch('/api/users')
.then((res) => res.json())
.then((data) => {
setUsers(data);
setLoading(false);
})
.catch((err) => {
setError('数据获取失败');
setLoading(false);
console.error(err);
});
}, []);
if (loading) return <div>加载中...</div>;
if (error) return <div style={{ color: 'red' }}>{error}</div>;
return (
<div>
<h1>Next.js + MySQL 用户列表</h1>
<ul>
{users.map((user: { id: number; name: string; email: string }) => (
<li key={user.id}>
{user.name} - {user.email}
</li>
))}
</ul>
</div>
);
}
12.启动项目并测试
npm run dev
访问 http://localhost:3000 即可看到用户列表,同时可通过以下地址测试API:
http://localhost:3000/api/users(获取所有用户)http://localhost:3000/api/users/1(获取ID为1的用户)
核心知识点总结
- Prisma 作用:作为ORM工具,简化MySQL的CRUD操作,自动生成类型定义(TypeScript友好)。
- 连接流程:通过
.env配置数据库连接 → 定义schema.prisma数据模型 → 迁移生成表 → 编写API/页面调用数据。 - 扩展性:可基于此流程扩展更多表、复杂查询(关联查询、筛选、分页等),或集成ECharts等可视化库实现大屏需求。
748

被折叠的 条评论
为什么被折叠?



