Prisma 입문 가이드
Prisma ORM 완벽 가이드 🚀
Section titled “Prisma ORM 완벽 가이드 🚀”Prisma가 뭐야? (What is Prisma?)
Section titled “Prisma가 뭐야? (What is Prisma?)”Prisma는 Next-generation Node.js & TypeScript ORM이야. 기존의 ORM들과 달리 Type-safe하고 Auto-completion이 완벽하게 지원되는 게 특징이지.
Prisma의 주요 구성 요소
Section titled “Prisma의 주요 구성 요소”왜 Prisma를 써야 할까? 🤔
Section titled “왜 Prisma를 써야 할까? 🤔”전통적인 방식과 비교해보면 차이가 확실해:
// SQL 직접 작성 - Error-prone!const users = await db.query( 'SELECT * FROM users WHERE age > $1 AND active = $2', [18, true]);// Type-safe & Auto-completion 지원!const users = await prisma.user.findMany({ where: { age: { gt: 18 }, active: true }});빠른 시작 (Quick Start) 🏃♂️
Section titled “빠른 시작 (Quick Start) 🏃♂️”1. 프로젝트 초기화
Section titled “1. 프로젝트 초기화”# 새 프로젝트 생성mkdir prisma-tutorial && cd prisma-tutorialnpm init -y
# TypeScript 설정 (선택사항이지만 강력 추천!)npm install -D typescript ts-node @types/nodenpx tsc --init
# Prisma 설치 (prisma CLI는 dev dependency, client는 production dependency)npm install -D prismanpm install @prisma/client2. Prisma 초기화
Section titled “2. Prisma 초기화”npx prisma init이 명령어가 생성하는 것들:
prisma/schema.prisma- 데이터베이스 스키마 정의 파일.env- 환경 변수 파일 (DATABASE_URL 포함).gitignore- Git에서 .env 파일 제외
Schema 정의하기 📝
Section titled “Schema 정의하기 📝”prisma/schema.prisma 파일에서 데이터베이스 구조를 정의해보자:
// 데이터베이스 연결 설정datasource db { provider = "postgresql" // mysql, sqlite, mongodb도 가능! url = env("DATABASE_URL")}
// Prisma Client 생성 설정generator client { provider = "prisma-client-js"}
// User 모델 정의model User { id Int @id @default(autoincrement()) email String @unique name String? role Role @default(USER) posts Post[] // 1:N relation profile Profile? // 1:1 relation createdAt DateTime @default(now()) updatedAt DateTime @updatedAt}
// Post 모델model Post { id Int @id @default(autoincrement()) title String content String? published Boolean @default(false) author User @relation(fields: [authorId], references: [id]) authorId Int categories Category[] // M:N relation createdAt DateTime @default(now())}
// Category 모델model Category { id Int @id @default(autoincrement()) name String @unique posts Post[]}
// Profile 모델model Profile { id Int @id @default(autoincrement()) bio String user User @relation(fields: [userId], references: [id]) userId Int @unique}
// Enum 정의enum Role { USER ADMIN}Prisma Schema의 핵심 개념
Section titled “Prisma Schema의 핵심 개념”Migration 실행하기 🔄
Section titled “Migration 실행하기 🔄”Schema를 정의했으니 이제 실제 데이터베이스에 반영해보자:
# 개발 환경에서 마이그레이션 생성 및 적용npx prisma migrate dev --name init
# Production 환경에서는npx prisma migrate deployPrisma Client 사용하기 💻
Section titled “Prisma Client 사용하기 💻”기본 CRUD Operations
Section titled “기본 CRUD Operations”import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() { // CREATE - 새 사용자 생성 const user = await prisma.user.create({ data: { email: 'alice@prisma.io', name: 'Alice', posts: { create: { title: 'Hello World', content: 'My first post!' } } }, include: { posts: true } }) console.log(user)
// READ - 모든 사용자 조회 const users = await prisma.user.findMany({ where: { email: { contains: 'prisma.io' } }, include: { posts: { where: { published: true } } } })
// UPDATE - 사용자 정보 수정 const updatedUser = await prisma.user.update({ where: { email: 'alice@prisma.io' }, data: { name: 'Alice Kim' } })
// DELETE - 사용자 삭제 const deletedUser = await prisma.user.delete({ where: { email: 'alice@prisma.io' } })}
main() .catch((e) => { throw e }) .finally(async () => { await prisma.$disconnect() })Advanced Queries
Section titled “Advanced Queries”// Aggregation - 집계 함수const userCount = await prisma.user.count({ where: { posts: { some: { published: true } } }})
// Grouping - 그룹화const groupedPosts = await prisma.post.groupBy({ by: ['published'], _count: { _all: true }})
// Transaction - 트랜잭션const [user, post] = await prisma.$transaction([ prisma.user.create({ data: { email: 'bob@prisma.io', name: 'Bob' } }), prisma.post.create({ data: { title: 'Join the Prisma Community', authorId: 1 } })])
// Raw SQL - 필요할 때 직접 SQL 실행const result = await prisma.$queryRaw` SELECT * FROM "User" WHERE email = ${email}`Prisma Studio 사용하기 🎨
Section titled “Prisma Studio 사용하기 🎨”Prisma Studio는 데이터베이스를 시각적으로 탐색하고 편집할 수 있는 GUI 도구야:
npx prisma studio브라우저에서 http://localhost:5555로 접속하면 다음과 같은 기능을 사용할 수 있어:
- 데이터 조회 및 필터링
- 데이터 추가, 수정, 삭제
- 관계 탐색
- 데이터 내보내기
Best Practices & Tips 💡
Section titled “Best Practices & Tips 💡”1. Type Generation 활용하기
Section titled “1. Type Generation 활용하기”Prisma는 Schema를 기반으로 TypeScript 타입을 자동 생성해줘:
import { User, Post, Prisma } from '@prisma/client'
// Prisma가 생성한 타입 활용type UserWithPosts = Prisma.UserGetPayload<{ include: { posts: true }}>
function displayUser(user: UserWithPosts) { console.log(`${user.name} has ${user.posts.length} posts`)}2. Client Extensions 사용하기
Section titled “2. Client Extensions 사용하기”참고: Prisma 4.16.0 이전에 사용되던
prisma.$use()미들웨어 API는 deprecated 되었다. 현재 권장되는 방식은$extends()를 사용한 Client Extensions이다.
// Client Extensions를 이용한 쿼리 로깅const prisma = new PrismaClient().$extends({ query: { $allModels: { async $allOperations({ model, operation, args, query }) { const before = Date.now() const result = await query(args) const after = Date.now()
console.log(`Query ${model}.${operation} took ${after - before}ms`) return result }, }, },})
// Soft Delete 구현const xprisma = prisma.$extends({ query: { user: { async delete({ args, query }) { return prisma.user.update({ where: args.where, data: { deletedAt: new Date() }, }) }, }, },})3. Connection Pooling
Section titled “3. Connection Pooling”Production 환경에서는 connection pool 설정이 중요해:
DATABASE_URL="postgresql://user:password@localhost:5432/mydb?connection_limit=5"4. Seeding 데이터
Section titled “4. Seeding 데이터”개발 환경에서 테스트 데이터를 자동으로 생성하려면:
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() { const alice = await prisma.user.upsert({ where: { email: 'alice@prisma.io' }, update: {}, create: { email: 'alice@prisma.io', name: 'Alice', posts: { create: [ { title: 'Check out Prisma with Next.js', content: 'https://www.prisma.io/nextjs', published: true, }, { title: 'Follow Prisma on Twitter', content: 'https://twitter.com/prisma', published: true, }, ], }, }, })
console.log({ alice })}
main() .catch((e) => { console.error(e) process.exit(1) }) .finally(async () => { await prisma.$disconnect() })package.json에 seed 스크립트 추가:
{ "prisma": { "seed": "ts-node prisma/seed.ts" }}이제 Prisma의 기본을 마스터했어! 다음 단계로는:
- Prisma with GraphQL - Nexus나 TypeGraphQL과 함께 사용하기
- Prisma with REST API - Express나 Fastify와 통합하기
- Advanced Patterns - Repository 패턴, Unit of Work 구현하기
- Performance Optimization - Query 최적화, N+1 문제 해결하기