Next.js 数据库集成 🗄️
🎯 概述
Next.js 支持多种数据库集成方案,包括 Prisma、Drizzle、MongoDB 等,适用于不同的应用场景。
📦 Prisma (推荐)
安装
bash
npm install prisma @prisma/client
npx prisma init定义模型
prisma
// prisma/schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String @id @default(cuid())
email String @unique
name String?
posts Post[]
createdAt DateTime @default(now())
}
model Post {
id String @id @default(cuid())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId String
createdAt DateTime @default(now())
}生成客户端
bash
npx prisma generate
npx prisma db push使用 Prisma
tsx
// lib/prisma.ts
import { PrismaClient } from '@prisma/client'
const globalForPrisma = global as unknown as { prisma: PrismaClient }
export const prisma = globalForPrisma.prisma || new PrismaClient()
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
// app/api/posts/route.ts
import { prisma } from '@/lib/prisma'
import { NextResponse } from 'next/server'
export async function GET() {
const posts = await prisma.post.findMany({
include: { author: true }
})
return NextResponse.json(posts)
}
export async function POST(request: Request) {
const { title, content, authorId } = await request.json()
const post = await prisma.post.create({
data: { title, content, authorId }
})
return NextResponse.json(post)
}🚀 MongoDB
安装
bash
npm install mongodb连接数据库
tsx
// lib/mongodb.ts
import { MongoClient } from 'mongodb'
const uri = process.env.MONGODB_URI!
const options = {}
let client: MongoClient
let clientPromise: Promise<MongoClient>
if (process.env.NODE_ENV === 'development') {
const globalWithMongo = global as typeof globalThis & {
_mongoClientPromise?: Promise<MongoClient>
}
if (!globalWithMongo._mongoClientPromise) {
client = new MongoClient(uri, options)
globalWithMongo._mongoClientPromise = client.connect()
}
clientPromise = globalWithMongo._mongoClientPromise
} else {
client = new MongoClient(uri, options)
clientPromise = client.connect()
}
export default clientPromise使用 MongoDB
tsx
// app/api/users/route.ts
import clientPromise from '@/lib/mongodb'
import { NextResponse } from 'next/server'
export async function GET() {
const client = await clientPromise
const db = client.db('myapp')
const users = await db.collection('users').find({}).toArray()
return NextResponse.json(users)
}
export async function POST(request: Request) {
const data = await request.json()
const client = await clientPromise
const db = client.db('myapp')
const result = await db.collection('users').insertOne(data)
return NextResponse.json(result)
}📝 Drizzle ORM
安装
bash
npm install drizzle-orm postgres
npm install -D drizzle-kit定义模式
tsx
// db/schema.ts
import { pgTable, serial, text, timestamp, boolean } from 'drizzle-orm/pg-core'
export const users = pgTable('users', {
id: serial('id').primaryKey(),
email: text('email').notNull().unique(),
name: text('name'),
createdAt: timestamp('created_at').defaultNow()
})
export const posts = pgTable('posts', {
id: serial('id').primaryKey(),
title: text('title').notNull(),
content: text('content'),
published: boolean('published').default(false),
authorId: serial('author_id').references(() => users.id),
createdAt: timestamp('created_at').defaultNow()
})使用 Drizzle
tsx
// lib/db.ts
import { drizzle } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
import * as schema from '@/db/schema'
const client = postgres(process.env.DATABASE_URL!)
export const db = drizzle(client, { schema })
// app/api/posts/route.ts
import { db } from '@/lib/db'
import { posts } from '@/db/schema'
import { eq } from 'drizzle-orm'
export async function GET() {
const allPosts = await db.select().from(posts)
return NextResponse.json(allPosts)
}
export async function POST(request: Request) {
const data = await request.json()
const newPost = await db.insert(posts).values(data).returning()
return NextResponse.json(newPost[0])
}📚 最佳实践
1. 连接池管理
tsx
// lib/prisma.ts
import { PrismaClient } from '@prisma/client'
const prismaClientSingleton = () => {
return new PrismaClient({
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
})
}
declare global {
var prisma: undefined | ReturnType<typeof prismaClientSingleton>
}
const prisma = globalThis.prisma ?? prismaClientSingleton()
export default prisma
if (process.env.NODE_ENV !== 'production') globalThis.prisma = prisma2. 错误处理
tsx
export async function GET() {
try {
const posts = await prisma.post.findMany()
return NextResponse.json(posts)
} catch (error) {
console.error('数据库错误:', error)
return NextResponse.json(
{ error: '获取数据失败' },
{ status: 500 }
)
}
}3. 事务处理
tsx
// Prisma 事务
const result = await prisma.$transaction(async (tx) => {
const user = await tx.user.create({ data: { email: 'test@example.com' } })
const post = await tx.post.create({ data: { title: 'Hello', authorId: user.id } })
return { user, post }
})🔗 相关资源
下一步:学习 Next.js 国际化 (i18n)。