오늘은 지난 시간에 이어 공식문서를 보면서 nestJS에서 Prisma와 Mysql를 설치하고 연결해보려고 한다.
개인적인 공부를 위해 작성하는 블로그입니다. 혹시라도 잘못되거나 부족한 부분이 있다면 댓글로 알려주시면 감사하겠습니다.
👨🏻💻 Mysql 설치
Mysql은 대표적인 관계형 db 관리 시스템으로 세계에서 가장 널리 사용되는 오픈소스 데이터베이스 중 하나이다.
https://www.codeit.kr/tutorials/5/MySQL-%EC%84%A4%EC%B9%98-macOS
공식 홈페이지에서 받아도 괜찮고 brew로 받아주어도 괜찮다.
brew install mysql
설치가 완료되면 서버를 시작해 보자
brew services start mysql
다음 명령어를 실행하면 서버가 정상적으로 실행 중인지 확인할 수 있다.
brew services list
mysql_secure_installation를 터미널에 입력해 패스워드를 설정해 주고 다음 명령어로 클라이언트에 접속할 수 있다.
mysql -u root
💁🏻 Prisma 설치
Prisma는 TypeScript와 Node.js 환경에서 사용되는 오픈소스 ORM(Object-Relational Mapping)이다. 데이터베이스와 애플리케이션 간의 상호작용을 쉽게 관리할 수 있도록 돕는 도구로, SQL을 직접 작성하는 대신 타입 안전한 방식으로 데이터를 다룰 수 있다.
$ npm install prisma --save-dev
prisma가 설치되었다면 prizma cli를 사용해서 접두어 npx를 붙이고(권장) init으로 초기세팅을 해준다.
npx prisma init
- schema.prisma: 데이터베이스 연결을 지정하고 데이터베이스 스키마를 포함함
- .env: 일반적으로 환경 변수 그룹에 데이터베이스 자격 증명을 저장하는 데 사용됨
그럼 이렇게 prizma 폴더에 shema.prizma라는 파일이 생겼을 텐데 이곳에 들어가서 사용할 db에 대한 정보를 입력해 준다.
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
그리고. env 파일 DATABASE_URL에 Mysql에서 설정했던 username, password와 연결할 db 이름을 넣어준다.
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
DATABASE_URL="mysql://root:1234@127.0.0.1:3306/myTestDB"
#mysql://<username>:<password>@<host>:<port>/<database_name>
👩🏻🚀 prisma schema model 정의
schema.prisma에 다음과 같이 Puzzle, User, Feedback, Comment의 schema를 작성해 주었다.
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model Puzzle {
id Int @id @default(autoincrement())
title String
gameType String // "remove" || "move"
limit Int
difficulty String @default("Unrated")// "Easy", "Normal", "Hard", "Extreme"
initialState Json // 초기 상태
solution Json // 솔루션 (TODO: 분리하거나 암호화)
category Json // 문자열 배열 저장
createBy String // 만든 유저 아이디
likes Int @default(0) // 좋아요 수
attemptedCount Int @default(0) // 시도한 유저 수
correctCount Int @default(0) // 정답을 맞힌 유저 수
totalFeedbackScore Int @default(0) // 피드백 점수 총합
feedbackCount Int @default(0) // 피드백을 남긴 유저 수
createAt DateTime @default(now()) // 생성 시간 자동 기록
feadbacks Feedback[]
comments Comment[]
solvedByUsers User[] @relation("SolvedPuzzles")
attemptedByUsers User[] @relation("AttemptedPuzzles")
}
model Feedback {
id Int @id @default(autoincrement())
userId Int
puzzleId Int
score Int // 피드백 점수(1 ~ 10)
createAt DateTime @default(now())
user User @relation(fields: [userId], references: [id])
puzzle Puzzle @relation(fields: [puzzleId], references: [id])
}
model User {
id Int @id @default(autoincrement())
username String @unique
email String @unique // 이메일 (로그인용)
password String // 해싱된 패스워드
level Int @default(1) // 유저 레벨
solvedPuzzles Puzzle[] @relation("SolvedPuzzles")
attemptedPuzzles Puzzle[] @relation("AttemptedPuzzles")
feedbacks Feedback[]
comments Comment[]
}
model Comment {
id Int @id @default(autoincrement())
content String // 댓글 내용
createdAt DateTime @default(now()) // 작성 시간
updatedAt DateTime @updatedAt
userId Int
puzzleId Int
user User @relation(fields: [userId], references: [id])
puzzle Puzzle @relation(fields: [puzzleId], references: [id])
}
스키마를 Mysql db에 반영하려면 다음과 같은 명령어를 입력해 주면 된다.
npx prisma migrate dev --name init
npx prisma generate
그럼 이렇게 눈 깜짝할 사이에 SQL 쿼리문으로 만들어진걸 볼 수 있다. 확인 해보려면 다음 명령어를 쉘창에 입력해보자
npx prisma studio
@prisma/client를 받아주면 다음과 같이 PrismaClient를 가져와 사용할 수 있다.
$ npm install @prisma/client
prisma client : Prisma를 통해 데이터베이스와 상호작용할 수 있는 클라이언트 라이브러리, 데이터 조회, 생성, 업데이트, 삭제 작업을 Type-safe하고 간편하게 수행할 수 있다.
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
데이터 조회(Read)
// 모든 레코드 조회: findMany
const users = await prisma.user.findMany();
console.log(users);
// 조건에 맞는 레코드 조회: findMany + where
const activeUsers = await prisma.user.findMany({
where: { isActive: true },
})
console.log(activeUsers);
// 단일 레코드 조회: findUnique
const user = await prisma.user.findUnique({
where: { id: 1 },
});
console.log(user);
데이터 생성(Create)
// 단일 레코드 생성
const newUser = await prisma.usercreate({
data: {
username: "seungho",
email: "123@naver.com",
password: "hashed_password",
level: 1,
},
});
데이터 수정(Update)
// 단일 레코드 수정
const updatedUser = await prisma.user.update({
where: { id: 1 },
data: { level: 2},
})
데이터 삭제(Delete)
// 단일 레코드 삭제
const deletedUsesr = await prisma.user.delete({
where: { id: 1 },
})
마지막으로 prisma.service.ts 파일을 만들고 모듈 providers에 등록시켜준다. NestJS에서는 Java의 Bean과 유사하게 데이터베이스 커넥션이나 서비스 객체를 @Injectable() 데코레이터를 통해 Ioc 컨테이너에 등록하고 싱글톤 객체로 관리된다.
싱글톤(Singleton)은 소프트웨어 디자인 패턴 중 하나로, 클래스의 인스턴스를 오직 하나만 생성하고 이를 전역적으로 접근할 수 있도록 보장하는 패턴이다.
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
// OnModuleInit()를 통해 NestJS 수명 주기와 prisma를 연결해준다.
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
}
}
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { PuzzlesModule } from './puzzles/puzzles.module';
import { PrismaService } from './prisma.service';
@Module({
imports: [PuzzlesModule],
controllers: [AppController],
providers: [AppService, PrismaService],
})
export class AppModule {}
'개발 > 개발로그' 카테고리의 다른 글
[React] 성냥퍼즐 웹 서비스 만들기 13일차 (nodemailer, bcrypt, JWT) (0) | 2024.12.21 |
---|---|
[React] 성냥퍼즐 웹 서비스 만들기 12일차 (ValidationPipe) (0) | 2024.12.19 |
[React] 간단한 성냥퍼즐 웹 서비스 만들기 10일차 (Nest.js) (0) | 2024.12.13 |
[React] 간단한 성냥퍼즐 웹 서비스 만들기 9일차 (정답 검증 구현) (1) | 2024.12.09 |
[React] 간단한 성냥퍼즐 웹 서비스 만들기 8일차 (게임 타입, 횟수 제한 구현) (0) | 2024.12.05 |