Next.js와 Prisma를 이용한 데이터베이스 연결 및 관리
ㆍProject Diary/Next.js + Prisma + MariaDB (KiloFlow)
Pisma란?
- 프리즈마(Prisma)는 ORM(Object-Relational Mapping) 도구로, 데이터베이스와 상호작용하는 것을 단순화하고 타입 안전성을 제공하는 TypeScript 및 Node.js 프로젝트에서 사용되는 라이브러리입니다.
- 프리즈마는 데이터베이스 스키마를 정의하고, 타입안전성에 도움이 됩니다.
프리즈마 사용 방법
1. 프리즈마 설치
npm install @prisma/client
npm install prisma --save-dev
2. 프리즈마 초기화
프로젝트 루트 디렉토리에서 프리즈마를 초기화하여 기본 설정 파일을 생성합니다.
npx prisma init
생성되는 설정 파일
- prisma>schema.prisma : 데이터베이스 스키마를 정의하는 파일
- .env : 데이터베이스 연결 문자열을 포함하는 환경 변수 파일
3. 데이터베이스 연결 설정
.env 파일에서 데이터베이스 연결 문자열을 설정합니다.
// .env
DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"
// kiloflow 예시
DATABASE_URL="mysql://root:{password}4@localhost:3306/kiloflow"
4. 데이터베이스 스키마 정의
prisma>schema.prisma 파일에서 데이터베이스 모델을 정의합니다.
// prisma/schema.prisma
datasource db {
provider = "mysql" // 사용하려는 데이터베이스에 따라 provider를 변경 (예: postgresql, sqlite 등)
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
// 모델 작성 예시
model users {
user_id Int @id @default(autoincrement())
email String @unique
password String
nickname String @unique
profile_image String @default("default_image_url")
isInitialSetupComplete Boolean @default(false)
created_at DateTime @default(now())
userProfile UserProfile?
@@index([user_id])
}
5.마이그레이션 생성 및 적용
마이그레이션 이란?
데이터베이스 스키마의 변경 사항을 코드로 기록하고, 이 변경 사항을 데이터베이스에 반영하는 방법
npx prisma migrate dev --name init
- 마이그레이션 생성
- 파일은 스키마 변경 사항을 포함하는 마이그레이션 파일 생성
- '--name' 옵션은 마이그레이션의 이름을 지정
- 예시 : npx prisma migrate dev --name addUser
- 마이그레이션 적용
- 마이그레이션 파일이 생성되면, 프리즈마는 이를 데이터베이스에 적용하여 데이터베이스 구조를 업데이트
6. 프리즈마 클라이언트 생성
npx prisma generate
7. 프리즈마 클라이언트 사용
프리즈마 클라이언트를 사용하여 데이터베이스와 상호작용하는 코드를 작성합니다.
// lib/prisma.ts
import { PrismaClient } from "@prisma/client";
// 프리즈마 클라이언트 인스턴스 생성
const prisma = new PrismaClient();
export default prisma;
8. 실제 데이터베이스 쿼리에 적용 예시
(이메일 중복 확인 api엔드포인트)
// pages/api/auth/check.ts
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "../../../lib/prisma";
// API 핸들러 함수
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const { email, nickname } = req.query;
// 이메일 중복 확인
if (email) {
const userByEmail = await prisma.users.findUnique({
where: { email: email as string },
});
// 이미 존재하는 이메일인 경우
if (userByEmail) {
return res.status(200).json({ message: "이미 존재하는 이메일입니다.", available: false });
} else {
// 사용 가능한 이메일인 경우
return res.status(200).json({ message: "사용 가능한 이메일입니다.", available: true });
}
}
// 닉네임 중복 확인
if (nickname) {
const userByNickname = await prisma.users.findFirst({
where: { nickname: nickname as string },
});
// 이미 존재하는 닉네임인 경우
if (userByNickname) {
return res.status(200).json({ message: "이미 존재하는 닉네임입니다.", available: false });
} else {
// 사용 가능한 닉네임인 경우
return res.status(200).json({ message: "사용 가능한 닉네임입니다.", available: true });
}
}
// 잘못된 요청 처리
return res.status(400).json({ message: "잘못된 요청입니다." });
}