Prisma‌ 学习笔记

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等可视化库实现大屏需求。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值