728x90

이제 PrismaService를 NestJS에 성공적으로 통합했으므로, 실제 데이터베이스 작업을 수행하는 CRUD(Create, Read, Update, Delete) 기본 기능과 복합 쿼리 사용법을 알아보겠습니다. 모든 예시는 PrismaService 내에서 상속받은 this.prisma.<modelName>을 통해 접근하는 메서드라고 가정합니다.
3.1. 데이터 생성 (Create)
🌟 create 및 DTO를 이용한 안전한 생성
단일 레코드를 생성할 때 사용합니다. NestJS에서는 요청 본문(request body)의 유효성을 검사하고 데이터 구조를 정의하는 DTO (Data Transfer Object)를 사용하여 안전하게 데이터를 받습니다.
사용 예시 (User 생성):
// DTO (예시)
class CreateUserDto {
email: string;
name?: string;
}
// 서비스 코드
async createUser(data: CreateUserDto) {
// Prisma는 받은 DTO를 data 속성을 통해 직접 사용합니다.
return this.prisma.user.create({
data: {
email: data.email,
name: data.name,
// 필요한 경우 여기에 추가 필드 설정
},
});
}
🎈 createMany를 이용한 다중 생성
단일 쿼리로 여러 레코드를 생성할 때 사용합니다. 이는 단일 create를 여러 번 호출하는 것보다 훨씬 효율적입니다.
사용 예시:
async createMultipleUsers(data: CreateUserDto[]) {
return this.prisma.user.createMany({
data: data, // DTO 배열
skipDuplicates: true, // 선택 사항: 중복된 레코드는 건너뛸지 여부
});
// 반환 값: { count: number } - 실제로 생성된 레코드 수
}
3.2. 데이터 조회 (Read)
🔑 단일 조회 (findUnique)
고유 필드(예: @id 또는 @unique가 설정된 필드)를 기준으로 단 하나의 레코드를 조회합니다.
// ID를 기준으로 조회
async findUserById(id: number) {
return this.prisma.user.findUnique({
where: {
id: id,
},
// select: 특정 필드만 선택
// include: 관계된 모델(Post 등)을 함께 가져옴 (N+1 문제 방지)
});
}
📚 목록 조회 (findMany) 및 조건 필터링
여러 레코드를 조회할 때 사용하며, 강력한 where 조건을 통해 필터링합니다.\
async findPublishedPosts(authorEmail: string) {
return this.prisma.post.findMany({
where: {
published: true, // Boolean 필터링
title: {
contains: 'Prisma', // 제목에 'Prisma'가 포함된 경우
},
// 관계된 모델을 통한 필터링
author: {
is: {
email: authorEmail, // 작성자의 이메일이 일치하는 경우
},
},
},
// 복합 쿼리 옵션 (3.4절 참고): orderBy, take, skip
});
}
3.3. 데이터 수정 및 삭제 (Update & Delete)
✏️ 단일 수정 (update)
고유 필드를 기준으로 단 하나의 레코드를 찾아서 수정합니다.
async updateUserName(id: number, newName: string) {
return this.prisma.user.update({
where: {
id: id,
},
data: {
name: newName,
},
});
}
✏️ 조건부 다중 수정 (updateMany)
where 조건에 맞는 모든 레코드를 한 번에 수정합니다.\
async unpublishAllPosts() {
return this.prisma.post.updateMany({
where: {
published: true, // 발행된 모든 게시물
},
data: {
published: false, // 미발행으로 변경
},
});
// 반환 값: { count: number } - 수정된 레코드 수
}
🗑️ 단일 삭제 (delete) 및 다중 삭제 (deleteMany)
- delete: 고유 필드를 기준으로 하나의 레코드를 삭제합니다.
- deleteMany: where 조건에 맞는 모든 레코드를 한 번에 삭제합니다.
// 단일 삭제
async deleteUser(id: number) {
return this.prisma.user.delete({
where: {
id: id,
},
});
}
// 다중 삭제
async deleteDraftPosts() {
return this.prisma.post.deleteMany({
where: {
published: false,
},
});
// 반환 값: { count: number } - 삭제된 레코드 수
}
3.4. 복합 쿼리: 페이징, 정렬, 검색
Prisma의 findMany 메서드는 데이터 처리의 효율성을 높이는 복합 쿼리 옵션을 제공합니다.
📜 페이징 (Paging): take와 skip
대규모 데이터셋에서 특정 범위의 데이터만 가져올 때 사용합니다.
- take: 가져올 레코드의 최대 개수 (Limit)를 지정합니다.
- skip: 건너뛸 레코드의 개수 (Offset)를 지정합니다.
async getPaginatedPosts(page: number, pageSize: number) {
const skip = (page - 1) * pageSize;
return this.prisma.post.findMany({
skip: skip, // 1페이지는 0, 2페이지는 pageSize만큼 건너뜀
take: pageSize, // 한 페이지당 가져올 개수
});
}
↕️ 정렬 (Sorting): orderBy
결과를 특정 필드를 기준으로 정렬합니다.
async getLatestUsers() {
return this.prisma.user.findMany({
orderBy: {
id: 'desc', // ID를 기준으로 내림차순 (최신순) 정렬
// 여러 필드로 정렬: [{ name: 'asc' }, { createdAt: 'desc' }]
},
});
}
🔍 검색 (Searching): contains, startsWith, mode
where 절 내에서 문자열 검색을 수행합니다.
| 필터 | 설명 |
| contains | 해당 문자열을 포함하는 레코드 검색 (SQL의 LIKE '%term%') |
| startsWith | 해당 문자열로 시작하는 레코드 검색 (SQL의 LIKE 'term%') |
| endsWith | 해당 문자열로 끝나는 레코드 검색 (SQL의 LIKE '%term') |
| mode: 'insensitive' | 대소문자 구분 없이 검색 (PostgreSQL 등 지원 DB) |
async searchPostByTitle(searchTerm: string) {
return this.prisma.post.findMany({
where: {
title: {
contains: searchTerm,
mode: 'insensitive', // 대소문자 무시 (PostgreSQL 기준)
},
},
});
}
728x90
'Nest.js를 배워보자 > 15. NestJS & Prisma 완벽 가이드' 카테고리의 다른 글
| 🛡️ 5부. 고급 활용 및 데이터 무결성 (0) | 2025.12.03 |
|---|---|
| 🌐 4부. 관계형 데이터 쿼리 마스터하기 (0) | 2025.12.03 |
| 🛠️ 2부. NestJS 모듈 시스템에 Prisma 통합하기 (0) | 2025.12.03 |
| 🚀 1부.NestJS와 Prisma로 ORM 끝판왕 되기: 소개 및 기본 설정 (3) | 2025.12.03 |
| 📝 NestJS & Prisma 완벽 가이드 시리즈 목차 (0) | 2025.12.03 |