본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 11. 4. · 22 Views
Prisma ORM 기초부터 심화까지
Prisma는 타입 안전성을 제공하는 차세대 ORM입니다. 데이터베이스 스키마 정의부터 복잡한 쿼리, 트랜잭션 처리까지 실무에서 바로 활용 가능한 핵심 기능들을 다룹니다.
들어가며
이 글에서는 Prisma ORM 기초부터 심화까지에 대해 상세히 알아보겠습니다. 총 12가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.
목차
- Prisma_스키마_정의
- Prisma_Client_초기화
- 기본_CRUD_작업
- 관계형_데이터_조회
- 필터링과_정렬
- 트랜잭션_처리
- 집계_함수_사용
- Raw_Query_실행
- 미들웨어_활용
- 페이지네이션_구현
- Upsert_작업
- 연결_끊기와_리소스_정리
1. Prisma 스키마 정의
개요
Prisma 스키마 파일에서 데이터베이스 모델을 정의하는 방법입니다. 타입 안전성과 자동 완성을 제공합니다.
코드 예제
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
createdAt DateTime @default(now())
}
설명
@id로 기본키를 지정하고, @unique로 유니크 제약조건을 추가합니다. 관계형 필드(posts)로 다른 모델과의 연결을 정의할 수 있습니다.
2. Prisma Client 초기화
개요
Prisma Client를 생성하고 데이터베이스와 연결하는 기본 설정입니다. 싱글톤 패턴으로 재사용합니다.
코드 예제
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
export default prisma
설명
PrismaClient 인스턴스를 생성하여 데이터베이스 작업을 수행합니다. 애플리케이션 전체에서 하나의 인스턴스를 공유하는 것이 권장됩니다.
3. 기본 CRUD 작업
개요
Prisma로 데이터를 생성(Create), 조회(Read), 수정(Update), 삭제(Delete)하는 기본 작업입니다.
코드 예제
// Create
const user = await prisma.user.create({
data: { email: 'test@example.com', name: 'John' }
})
// Read
const users = await prisma.user.findMany()
// Update
await prisma.user.update({
where: { id: 1 },
data: { name: 'Jane' }
})
설명
직관적인 API로 데이터베이스 작업을 수행합니다. TypeScript 타입 추론으로 오타나 타입 오류를 컴파일 시점에 잡을 수 있습니다.
4. 관계형 데이터 조회
개요
include와 select를 사용하여 연관된 데이터를 함께 조회하는 방법입니다. N+1 문제를 방지합니다.
코드 예제
const userWithPosts = await prisma.user.findUnique({
where: { id: 1 },
include: {
posts: {
where: { published: true },
orderBy: { createdAt: 'desc' }
}
}
})
설명
include로 관련 데이터를 한 번의 쿼리로 가져옵니다. 중첩된 where와 orderBy로 세밀한 필터링이 가능합니다.
5. 필터링과 정렬
개요
where 조건으로 데이터를 필터링하고 orderBy로 정렬하는 고급 쿼리 기법입니다.
코드 예제
const filteredUsers = await prisma.user.findMany({
where: {
OR: [
{ email: { contains: 'gmail' } },
{ name: { startsWith: 'J' } }
]
},
orderBy: { createdAt: 'desc' },
take: 10
})
설명
OR, AND 연산자와 contains, startsWith 같은 필터를 조합합니다. take로 결과 개수를 제한하여 페이지네이션을 구현할 수 있습니다.
6. 트랜잭션 처리
개요
여러 데이터베이스 작업을 하나의 트랜잭션으로 묶어 원자성을 보장합니다. 실패 시 모두 롤백됩니다.
코드 예제
await prisma.$transaction(async (tx) => {
const user = await tx.user.create({
data: { email: 'user@test.com' }
})
await tx.post.create({
data: { title: 'First Post', userId: user.id }
})
})
설명
$transaction으로 여러 작업을 묶습니다. 하나라도 실패하면 전체가 롤백되어 데이터 일관성을 유지합니다.
7. 집계 함수 사용
개요
count, avg, sum, min, max 등의 집계 함수로 통계 데이터를 계산합니다.
코드 예제
const stats = await prisma.post.aggregate({
_count: { id: true },
_avg: { views: true },
_max: { createdAt: true },
where: { published: true }
})
console.log(stats._count.id, stats._avg.views)
설명
aggregate API로 데이터베이스 레벨에서 통계를 계산합니다. 대량의 데이터를 효율적으로 처리할 수 있습니다.
8. Raw Query 실행
개요
복잡한 쿼리나 Prisma가 지원하지 않는 기능을 사용할 때 원시 SQL을 직접 실행합니다.
코드 예제
const users = await prisma.$queryRaw`
SELECT * FROM User
WHERE email LIKE ${`%gmail%`}
AND createdAt > ${new Date('2024-01-01')}
`
설명
$queryRaw로 SQL을 직접 작성하되 템플릿 리터럴로 SQL 인젝션을 방지합니다. 복잡한 조인이나 서브쿼리에 유용합니다.
9. 미들웨어 활용
개요
모든 쿼리 실행 전후에 로직을 추가하는 미들웨어로 로깅, 인증, 데이터 변환 등을 구현합니다.
코드 예제
prisma.$use(async (params, next) => {
const before = Date.now()
const result = await next(params)
const after = Date.now()
console.log(`Query ${params.model}.${params.action} took ${after - before}ms`)
return result
})
설명
$use로 미들웨어를 등록합니다. 쿼리 성능 모니터링, 소프트 삭제 구현, 자동 타임스탬프 업데이트 등에 활용됩니다.
10. 페이지네이션 구현
개요
cursor 기반 또는 offset 기반 페이지네이션으로 대용량 데이터를 효율적으로 조회합니다.
코드 예제
// Cursor-based pagination
const posts = await prisma.post.findMany({
take: 10,
skip: 1,
cursor: { id: lastPostId },
orderBy: { id: 'asc' }
})
const nextCursor = posts[posts.length - 1]?.id
설명
cursor 기반 페이지네이션은 대용량 데이터에서 성능이 우수합니다. take로 가져올 개수, skip으로 커서 자체를 제외합니다.
11. Upsert 작업
개요
데이터가 존재하면 업데이트하고, 없으면 생성하는 upsert 연산입니다. 중복 처리 로직을 단순화합니다.
코드 예제
const user = await prisma.user.upsert({
where: { email: 'user@example.com' },
update: { name: 'Updated Name' },
create: {
email: 'user@example.com',
name: 'New User'
}
})
설명
where 조건으로 찾은 레코드가 있으면 update를, 없으면 create를 실행합니다. 원자적으로 처리되어 동시성 문제를 방지합니다.
12. 연결 끊기와 리소스 정리
개요
애플리케이션 종료 시 데이터베이스 연결을 안전하게 종료하여 리소스를 정리합니다.
코드 예제
async function main() {
// Your database operations
}
main()
.catch(console.error)
.finally(async () => {
await prisma.$disconnect()
})
설명
$disconnect()로 연결 풀을 정리합니다. 서버리스 환경에서는 각 요청 후, 장기 실행 앱에서는 종료 시 호출합니다.
마치며
이번 글에서는 Prisma ORM 기초부터 심화까지에 대해 알아보았습니다. 총 12가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.
관련 태그
#Prisma #ORM #TypeScript #Database #Schema
이 카드뉴스가 포함된 코스
댓글 (0)
함께 보면 좋은 카드 뉴스
마이크로서비스 배포 완벽 가이드
Kubernetes를 활용한 마이크로서비스 배포의 핵심 개념부터 실전 운영까지, 초급 개발자도 쉽게 따라할 수 있는 완벽 가이드입니다. 실무에서 바로 적용 가능한 배포 전략과 노하우를 담았습니다.
Application Load Balancer 완벽 가이드
AWS의 Application Load Balancer를 처음 배우는 개발자를 위한 실전 가이드입니다. ALB 생성부터 ECS 연동, 헬스 체크, HTTPS 설정까지 실무에 필요한 모든 내용을 다룹니다. 초급 개발자도 쉽게 따라할 수 있도록 단계별로 설명합니다.
RDS 연결과 관리 완벽 가이드
AWS RDS를 처음 접하는 개발자를 위한 실전 가이드입니다. 엔드포인트 확인부터 모니터링까지, 실무에서 꼭 알아야 할 RDS 관리 핵심 개념을 이북처럼 술술 읽히는 스토리로 풀어냈습니다. 데이터베이스 연결과 운영의 모든 것을 경험해보세요.
AWS RDS 데이터베이스 생성 완벽 가이드
AWS RDS를 처음 접하는 개발자를 위한 안내서입니다. 데이터베이스 인스턴스 생성부터 서브넷 그룹, 파라미터 그룹 설정까지 실무에 필요한 모든 것을 다룹니다. 초급 개발자도 쉽게 따라할 수 있도록 단계별로 설명합니다.
고객 상담 AI 시스템 완벽 구축 가이드
AWS Bedrock Agent와 Knowledge Base를 활용하여 실시간 고객 상담 AI 시스템을 구축하는 방법을 단계별로 학습합니다. RAG 기반 지식 검색부터 Guardrails 안전 장치, 프론트엔드 연동까지 실무에 바로 적용 가능한 완전한 시스템을 만들어봅니다.