개발자공부일기
Prisma 본문
Prisma는 Node.js 환경에서 사용되는 ORM(Object-Relational Mapping) 도구로, 데이터베이스와 애플리케이션 간의 상호작용을 간편하고 효율적으로 만들어줍니다. 기존 ORM과 달리 Prisma는 타입 안전성, 자동 완성 지원, 생산성 향상을 강조하며, 관계형 데이터베이스와 함께 작업할 때 특히 강력합니다.
Prisma의 구성 요소
Prisma는 다음 세 가지 주요 구성 요소로 이루어져 있습니다:
(1) Prisma Client
- Prisma의 ORM 도구로, 데이터베이스와 상호작용하기 위한 TypeScript/JavaScript 코드입니다.
- 타입 안전한 쿼리 작성을 지원하며, 자동 완성 기능으로 생산성을 높여줍니다.
- prisma generate 명령어를 통해 데이터베이스 스키마를 기반으로 클라이언트를 생성합니다.
(2) Prisma Schema
- Prisma가 데이터베이스를 관리하는 데 사용하는 설정 파일 (schema.prisma).
- 데이터 모델, 데이터베이스 연결 정보, 마이그레이션을 위한 정보를 정의합니다.
- 주요 구성:
- Data Source: 데이터베이스 종류 및 연결 정보를 정의.
- Generator: Prisma Client를 생성하는 방법 정의.
- Model: 데이터베이스 테이블과 매핑되는 데이터 구조 정의.
(3) Prisma Migrate
- 데이터베이스 스키마를 관리하고 버전 관리를 가능하게 해주는 도구.
- 데이터베이스 변경 사항을 마이그레이션 파일로 관리하며, 이를 실행해 데이터베이스를 업데이트합니다.
- 예를 들어, 테이블 추가/수정/삭제 같은 작업을 코드로 기록합니다.
Prisma 설치 및 기본 설정
(1) 프로젝트에 Prisma 설치
npm install prisma --save-dev npm install @prisma/client
(2) Prisma 초기화
npx prisma init
- 위 명령을 실행하면 다음과 같은 디렉토리와 파일이 생성됩니다:
- prisma/schema.prisma: Prisma 스키마 파일.
- .env: 데이터베이스 연결 문자열 및 환경 변수를 관리하는 파일.
(3) .env 파일 설정
데이터베이스 연결 문자열을 설정합니다. 예를 들어 MySQL:
.env
DATABASE_URL="mysql://user:password@localhost:3306/mydb"
Prisma Schema 작성
기본 예제
schema.prisma에서 데이터 모델을 정의합니다:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql" // 데이터베이스 종류: "postgresql", "sqlite", "mongodb" 등도 가능.
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
name String
email String @unique
createdAt DateTime @default(now())
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
authorId Int
author User @relation(fields: [authorId], references: [id])
}
주요 요소
- @id: 기본 키 설정.
- @default: 기본값 설정.
- @relation: 관계 설정 (1:N, N:M 등).
- ?: 필드가 선택적임을 나타냄.
Prisma Migrate 사용
마이그레이션 생성 및 실행
- 마이그레이션 생성
- 데이터베이스 스키마를 생성하고 마이그레이션 파일을 기록합니다.
npx prisma migrate dev --name init
2. 마이그레이션 실행
- npx prisma migrate dev를 실행하면 마이그레이션 파일에 따라 데이터베이스가 업데이트됩니다.
Prisma Client 사용
Prisma Client 생성
Prisma Client를 생성하려면 다음 명령어를 실행합니다:
npx prisma generate
Prisma Client 사용 예제
index.js에서 Prisma Client를 사용해 데이터베이스 작업을 수행합니다:
6Prisma의 장점
- 타입 안전성: TypeScript와 통합하여, 데이터베이스 작업이 타입 안전성을 보장받습니다.
- 생산성: 자동 완성 기능을 통해 코드 작성 속도가 빠릅니다.
- 강력한 쿼리 기능: 관계형 데이터베이스와의 복잡한 관계도 쉽게 처리할 수 있습니다.
- 다양한 데이터베이스 지원: MySQL, PostgreSQL, SQLite, SQL Server, MongoDB 등을 지원합니다.
7Prisma의 단점
- 복잡한 쿼리 제한: 매우 복잡한 쿼리나 데이터베이스 특정 기능 사용에는 제약이 있을 수 있습니다.
- 스키마 기반: 스키마 파일 관리가 필수적이라 유연성이 약간 제한될 수 있습니다.
- 초기 학습 곡선: 설정 및 사용법을 익히는 데 시간이 걸릴 수 있습니다.
Prisma의 추가 기능
- Prisma Studio: 데이터베이스의 데이터를 GUI로 시각화하고 관리할 수 있는 도구.
npx prisma studio
- 중첩 관계 쿼리: 관련된 데이터도 함께 가져오는 기능.
const userWithPosts = await prisma.user.findUnique({
where: { id: 1 },
include: { posts: true },
});
Prisma는 특히 Node.js와 TypeScript를 사용하는 프로젝트에서 데이터베이스와의 상호작용을 대폭 간소화하고, 개발 생산성을 극대화하는 데 유용합니다. 프로젝트에 따라 적절히 활용하면 큰 이점을 얻을 수 있습니다.
Prisma Client에서 자주 사용하는 CRUD 메서드
Prisma Client는 모델에 기반한 CRUD 메서드를 제공합니다. 각 메서드는 데이터베이스 테이블과 상호작용합니다.
(1) findUnique
- 단일 레코드를 기본 키 또는 고유 필드를 기준으로 조회합니다.
const user = await prisma.user.findUnique({
where: { email: 'alice@example.com' },
});
console.log(user);
(2) findMany
- 여러 레코드를 조회합니다. 필터링, 정렬, 페이징 등이 가능합니다.
const users = await prisma.user.findMany({
where: { name: { contains: 'Alice' } },
orderBy: { createdAt: 'desc' },
take: 5, // 상위 5개 레코드만 가져옴
});
console.log(users);
(3) create
- 새 레코드를 생성합니다.
const newUser = await prisma.user.create({
data: {
name: 'Bob',
email: 'bob@example.com',
},
});
console.log(newUser);
(4) update
- 기존 레코드를 수정합니다.
const updatedUser = await prisma.user.update({
where: { email: 'bob@example.com' },
data: { name: 'Bobby' },
});
console.log(updatedUser);
(5) delete
- 특정 레코드를 삭제합니다.
const deletedUser = await prisma.user.delete({
where: { email: 'bob@example.com' },
});
console.log(deletedUser);
데이터 조회 시 자주 사용하는 옵션
(1) select
- 특정 필드만 선택해서 가져옵니다.
const user = await prisma.user.findUnique({
where: { email: 'alice@example.com' },
select: { name: true, email: true },
});
console.log(user); // { name: 'Alice', email: 'alice@example.com' }
(2) include
- 관계 데이터를 포함해서 가져옵니다.
const userWithPosts = await prisma.user.findUnique({
where: { email: 'alice@example.com' },
include: { posts: true },
});
console.log(userWithPosts);
(3) where
- 필터링 조건을 정의합니다.
- 다양한 조건식 사용 가능:
- 단순 비교: equals, lt, lte, gt, gte, contains, startsWith, endsWith
- 배열 조건: in, notIn
- 논리 조건: AND, OR, NOT
const posts = await prisma.post.findMany({
where: {
OR: [
{ title: { contains: 'Prisma' } },
{ content: { contains: 'database' } },
],
},
});
console.log(posts);
(4) orderBy
- 결과를 정렬합니다.
const users = await prisma.user.findMany({
orderBy: { createdAt: 'desc' },
});
console.log(users);
(5) take와 skip
- 결과를 제한하거나 건너뜁니다.
const paginatedUsers = await prisma.user.findMany({
take: 10, // 최대 10개 가져옴
skip: 10, // 첫 10개는 건너뜀
});
console.log(paginatedUsers);
관계 데이터 처리
(1) 1:N 관계 처리
- 예제: 사용자가 작성한 게시글 추가
const userWithPost = await prisma.user.create({
data: {
name: 'Charlie',
email: 'charlie@example.com',
posts: {
create: [
{ title: 'My first post', content: 'Hello world!' },
{ title: 'Another post', content: 'More content here' },
],
},
},
include: { posts: true },
});
console.log(userWithPost);
(2) N:M 관계 처리
- 예제: 사용자가 여러 태그를 추가
model User {
id Int @id @default(autoincrement())
name String
tags Tag[] @relation("UserTags")
}
model Tag {
id Int @id @default(autoincrement())
name String
users User[] @relation("UserTags")
}
- 데이터 추가 예제:
const userWithTags = await prisma.user.create({
data: {
name: 'Eve',
tags: {
connectOrCreate: [
{ where: { name: 'Developer' }, create: { name: 'Developer' } },
{ where: { name: 'Designer' }, create: { name: 'Designer' } },
],
},
},
include: { tags: true },
});
console.log(userWithTags);
데이터 업데이트 및 삭제
(1) 중첩된 데이터 업데이트
- 예제: 게시글의 내용을 업데이트
const updatedUser = await prisma.user.update({
where: { email: 'charlie@example.com' },
data: {
posts: {
update: {
where: { id: 1 },
data: { content: 'Updated content!' },
},
},
},
});
console.log(updatedUser);
(2) 중첩된 데이터 삭제
- 예제: 특정 게시글 삭제
const updatedUser = await prisma.user.update({
where: { email: 'charlie@example.com' },
data: {
posts: {
delete: { id: 1 },
},
},
});
console.log(updatedUser);
Prisma의 고급 기능
(1) Raw 쿼리
- Prisma에서 SQL 쿼리를 직접 실행.
const result = await prisma.$queryRaw`SELECT * FROM User WHERE name = 'Alice'`;
console.log(result);
(2) Transaction
- 여러 작업을 하나의 트랜잭션으로 실행.
const [user, post] = await prisma.$transaction([
prisma.user.create({ data: { name: 'Dana', email: 'dana@example.com' } }),
prisma.post.create({ data: { title: 'Transaction Test', content: 'This is a test', authorId: 1 } }),
]);
console.log(user, post);
Prisma Studio
- Prisma Studio는 데이터베이스를 시각적으로 탐색하고 관리할 수 있는 GUI 도구입니다.
- 실행:
npx prisma studio
- 브라우저에서 데이터 편집 가능.
7. 활용 팁
- 코드 자동 완성: Prisma Client는 TypeScript를 기반으로 동작하므로, IDE에서 자동 완성을 통해 정확한 작업이 가능합니다.
- 타입 안전성: 모든 쿼리는 타입 안전성을 보장하므로, 런타임 오류를 줄일 수 있습니다.
- 마이그레이션 관리: Prisma Migrate를 통해 데이터베이스 구조를 코드로 관리하세요.
Prisma는 간단한 CRUD 작업부터 복잡한 데이터 관계 관리까지 모두 지원하여 생산성을 크게 높일 수 있는 도구입니다.
'TIL(Today I Learned)' 카테고리의 다른 글
OSI 7계층 (0) | 2024.11.26 |
---|---|
express-session (0) | 2024.11.26 |
RDBS, MySQL (0) | 2024.11.22 |
AWS배포하기 프로세스가 종료되지 않는 문제 (0) | 2024.11.21 |
1주차 서버와 클라이언트/ 웹 어플리케이션서버와 게임서버 (0) | 2024.11.20 |