이전 글에서 docker
를 이용해 mysql
을 띄웠고 이후 workbench를 이용해 데이터 베이스에 쉽게 접속할 수 있도록 만들었다.
그럼 이제 이를 실제로 코드상에서 사용해보려 하는데 Next.js
와 Prisma
를 이용해서 만들어보려고 한다.
이를 통해 prisma
의 사용법을 간단하게 보고 특히 Next.js
의 Server action을 잘 익혀볼 수 있을 것 같다.
npx create-next-app@latest
를 통해 간단한 next-app
을 만든다. 이름은 sql_test
로 만들었다.
성공적으로 sql_test
가 설치 되었다면 추가적으로 prisma
를 설치하자
cd sql_test
npm i prisma --save-dev
npx prisma init --datasource-provider mysql
혹시 sql_test
폴더가 아닌 바깥쪽에서 설치할 까 cd sql_test
도 넣었다.
무사히 잘 설치 했다면 sql_test
폴더 안에 prisma
라는 폴더가 생긴 걸 확인할 수 있다
이때 주의 할 점으로 만약
git
으로 해당 프로젝트를 올릴 생각을 하고 있다면 방금prisma
와 함께 생긴.env
파일을 되도록 git remote 에는 올리지 말아야 하는데.gitignore
에 들어가서.env
를 추가하자.
그럼 git의 추적이 끊어진 걸 볼 수 있다
prisma
폴더 안에는 schema.prisma
라는 파일이 하나 같이 생성되어 있는데 내부를 살펴보면
// 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")
}
이렇게 만들어져 있다. Prisma클라이언트를 생성하고 아래는 db를 연결하는데 mysql
이며 url
부분은 env()
를 통해 .env
파일에 접근 하여 DATABASE_URL
을 가져온다.
나는 .env
와 DATABASE_URL
을 만든적이 없는데 어떻게 된걸까? 프로젝트 루트 폴더에서 잘 살펴보면 .env
파일이 만들어져 있고 내부를 살펴보면
# 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://johndoe:randompassword@localhost:3306/mydb"
이렇게 존재하는 걸 확인할 수 있다.
url의 형식은 내가 사용하는 데이터베이스마다 형식이 다르니 각자 참고해서 넣어보자 MySQL
같은 경우는 아래와 같다.
mysql://USER:PASSWORD@HOST:PORT/DATABASE
임으로
USER
: 데이터베이스 사용자의 이름PASSWORD
: 데이터베이스 사용자의 비밀번호PORT
: 데이터베이스 서버가 실행중인 포트(일반적으로 MySQL의 경우 3306
이다)DATABASE
: 데이터베이스 이름우리는 저번에 만든 걸 넣어본다면
DATABASE_URL="mysql://dev:1234@localhost:3306/test"
가 될 것이다.
이러면 Prisma가 데이터 베이스에 접근할 수 있도록 성공적으로 작성했다. 이따가 테스트를 통해 잘 들어가는지 확인을 해보자
내가 넣고 싶은 건 간단하게 제목과 내용을 가진 글목록이고 이를 테이블로 만들어 보고 싶다.
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
title String @db.VarChar(255)
content String?
}
Post
라는 테이블에 다음과 같은 컬럼을 만든다
id
: Int
타입이며 @id
역할을 하고 @default
기본적으로 autoincrement
자동 증가하게 해준다. 즉, 자동적으로 증가하는 아이디가 붙을거란 것createdAt
: 생성 날짜인데 DateTime
타입이며 기본적으로 now
현재 시간으로 넣을것이다등 아래 title
과 content
는 찾아보며 유추 가능할 것이라 생각한다.
이렇게 prisma를 작성하고 다시 명령어 창으로 돌아와 아래의 명령어를 입력해주면?
npx prisma migrate dev --name init
우리가 작성한 prisma 모델이 올라가게 되고 migration
기록이 db에 함께 저장되게 된다!
우리 프로젝트에도 새로운 폴더와 파일이 생성되는데
prisma/migrations/2024...(마이그레이션시간)/migration.sql
이 만들어지게 된다. 이 내부를 확인해보면
CREATE TABLE `Post` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`title` VARCHAR(255) NOT NULL,
`content` VARCHAR(191) NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
'이처럼 되어 있는데 우리가 아까 prisma 파일에서 선언한 model을 prisma가 자동적으로 sql문으로 변경하여 데이터 베이스 서버에 날려주는 것이다.
고로 데이터 베이스를 확인하러 workbench로 들어가보면?
내가 설정한 model이 다 그대로 들어간 걸 확인할 수 있다. 여기까지 오면 굉장히 신기하고 또 재밋게 느껴졌다.
그럼 이 다음에는 클라이언트 쪽에서 무언가를 할 수 있어야 하는데..
여기서
공식문서에 따르면 prisma@client
를 새로 설치하라고 나오는데 설치하지 않고도 사용할 수 있었다. 아마 자동 설치되는 부분이 있는 것 같다.
그러면 아래의 설치를 따라하지 않고 한번 진행해보자
npm install @prisma/client
데이터 베이스에서 데이터를 읽고 쓰기 위한 쿼리 작성을 시작할 수 있는데
일단 prisma 의 인스턴스를 생성해 줘야 한다
lib/prisma.ts
라는 파일을 만들어 아래의 코드를 추가해주자
// lib/prisma.ts
import { PrismaClient } from "@prisma/client";
declare global {
let prisma: PrismaClient | undefined;
}
const client = prisma || new PrismaClient();
if (process.env.NODE_ENV !== "production") prisma = client;
export default client;
이는 prisma@client
를 따로 import
하지 않고 전역적으로 사용하기 위해 작성된 코드로 declare global
을 통해 글로벌 변수속 prisma
를 선언, 이후 client
를 만들어 만약 전역 변수 prisma
가 없다면 새로운 prisma@client
를 가지도록 하였고 아니라면 기존 글로벌 변수에 있는 prisma
를 사용하도록 한다.
이때 만약 노드의 상태가 프로덕션이면 client
는 prisma
전역변수에 할당하여 동일화 시킨 후 client
는 export
하여 전역적으로 사용할 수 있게 한다.
이를 통해 다른 곳에서 client
를 통해 prisma
가 제공하는 데이터베이스 쿼리를 사용할 수 있게 된다.
이는 다음 글에서 Next.js의 server action과 더불어 함께 다뤄보자
Reference : https://www.prisma.io/ , https://www.yujiseok.blog/post/nextjs-server-actions