Prisma คืออะไร?
Prisma คือ ORM (Object Relational Mapping) สำหรับ Next.js ซึ่ง Prisma จะช่วยให้เราสร้างโครงสร้างของ Database และอ่านเขียนข้อมูลได้ง่ายขึ้นโดยไม่ต้องใช้ SQL ซึ่งนั่นจะทำให้ Code ของเราปลอดภัยขึ้น
Prisma รองรับ Database ยอดนิยมหลายตัวดังนี้
- PostgreSQL
- MySQL
- SQLite
- SQL Server
- MongoDB
ซึ่งการใช้ ORM จะทำให้เราสามารถเปลี่ยน Database ได้ในอนาคต เช่นเราสามารถเปลี่ยนจาก MySQL ไปเป็น PostgreSQL ได้ แต่ถ้าเราเขียน SQL เข้าไปตรงๆ เราจะไม่สามารถเปลี่ยน Database ได้เลย
องค์ประกอบของ Prisma
ก่อนจะไปเรียนรู้การใช้งาน Prisma คุณต้องทำความเข้าใจ Components หลักๆเหล่านี้
-
Prisma Client: ทำหน้าที่สร้าง SQL Query ขึ้นมาจาก Code ที่เราเขียนด้วย TypeScript หรือ JavaScript
-
Prisma Schema: เป็นภาษาที่ใช้กำหนดโครงสร้างและความสัมพันธ์ของข้อมูลใน Database
-
Prisma Migrate: ทำหน้าที่สร้าง Database Schema ตามที่เราได้กำหนดไว้ใน
Prisma Schema
-
Prisma Studio: เป็น GUI สำหรับจัดการกับ Data ใน Database
Prisma Data Types
Prisma รองรับประเภทของ Data Type หรือ Field Types ต่างๆดังต่อไปนี้
- String
- Boolean
- Int
- BigInt
- Float
- Decimal
- DateTime
- Json
- Bytes
Field Attributes
เราสามารถใช้ Attributes ต่างๆเหล่านี้เพื่ออธิบายโครงสร้างของ Table ใน Database ที่เราต้องการได้
- @id: ระบุว่า Field นี้เป็น Primary Key
- @@id: ใช้สำหรับระบุว่า Primary Key นั้นเกิดจากการ Fields มากกว่า 1 Field(Composite Key)
- @default: กำหนดค่า Default ให้กับ Field นั้นๆ
- @unique: กำหนดให้ Field นี้มีค่าไม่ซ้ำกัน
- @@unique: กำหนดให้ข้อมูลห้ามตรงกันทุก Fields ที่กำหนด @@unique
- @index: กำหนดให้ Field นี้มี Index
- @relation: ระบุความสัมพันธ์(Relationship) กับ Table อื่นๆ
การติดตั้ง Prisma
การนำ Prisma เข้ามาใช้งานมีขั้นตอนต่างๆ ดังนี้
-
สร้าง Project Next.js ขึ้นมาใหม่ด้วยคำสั่ง
npx create-next-app my-app cd my-app
-
ติดตั้ง Prisma และ Adapter ที่ทำหน้าที่ติดต่อกับฐานข้อมูล ซึ่งในตัวอย่างนี้เราจะใช้ SQLite
npm install prisma --save-dev npm install @prisma/client
Initial Prisma และ Config Database
หลังจากที่เรานำ Prisma เข้ามาใน Project ของเราเรียบร้อยสิ่งที่ต้องทำต่อไปก็คือการสร้าง Config file ของ Prisma ซึ่งมีขั้นตอนต่างๆ ดังนี้
-
เริ่มต้นสร้างไฟล์ที่ Prisma ต้องการด้วยคำสั่ง
npx prisma init // หรือถ้าต้องการกำหนด Database ให้ใส่ argument เข้าไปแบบนี้ npx prisma init --datasource-provider sqlite
คำสั่งนี้จะสร้างไฟล์
prisma/schema.prisma
สำหรับกำหนดโครงสร้างของ Tables ต่างๆใน Database.env
สำหรับเก็บค่าตัวแปรต่างๆ เช่น DATABASE_HOST, DATABASE_USER และ DATABASE_PASSWORD
-
ตั้งค่า DATABASE_URL ไว้ในไฟล์
.env
โดยเราจะระบุ Path ของ file ที่จะเก็บข้อมูล(เนื่องจาก sqlite เก็บข้อมูลไว้ใน file)DATABASE_URL="file:./dev.db"
-
กำหนด Schema ของ Table ใน Database โดยที่เราจะระบุ Schema ไว้ในไฟล์
prisma/schema.prisma
ยกตัวอย่างเช่นgenerator client { provider = "prisma-client-js" } datasource db { provider = "sqlite" url = env("DATABASE_URL") } model User { id Int @id @default(autoincrement()) name String email String @unique posts Post[] } model Post { id Int @id @default(autoincrement()) title String content String? published Boolean @default(false) author User @relation(fields: [authorId], references: [id]) authorId Int }
Migration and Seeding
ตอนเรานำ Application ไปติดตั้งสิ่งที่เราควรจะต้องทำคือ เตรียม Database ให้พร้อมใช้งานโดยต้องมีทั้งโครงสร้าง(Schema) และ Data ที่พร้อมให้ Application สามารถเริ่มต้นได้เลยทันที โดยเฉพาะ Automated Deploy ซึ่งในบัจจุบัน Framework ต่างๆจะเตรียม Migration และ Seeding มาให้เราใช้งาน ดังนั้นในหัวข้อนี้เรามาดูวิธีการใช้งาน Migration และ Seeding บน Next.js ด้วย Prisma กัน
Migration
Migration คือเครื่องมือที่ช่วยสร้าง Table ที่มีโครงสร้างตามที่เรากำหนดไว้ในไฟล์ prisma/schema.prisma
เมื่อเราต้องการให้ Prisma สร้าง Table ให้เรา เราจะใช้คำสั่ง
npx prisma migrate dev --name init
ซึ่ง Prisma จะสร้างไฟล์ฐานข้อมูล dev.db
ที่มีโครงสร้างที่เราต้องการไว้ใน Path ปัจจุบัน และหลังจากที่เราสร้างโครงสร้างของ Database ขึ้นมาแล้ว เราสามารถเข้าไปดู Database ที่เราสร้างขึ้นได้ด้วย Prisma Studio โดยใช้คำสั่ง
npx prisma studio
หรือถ้าต้องการตรวจาสอบ SQL ที่ใช้สำหรับการ Migrate ให้เข้าไปดูในไฟล์ SQL ที่ถูกสร้างขึ้นมาที่ prisma/migrations/0_init/migration.sql
และะหลังจากนี้ถ้าต้องการ Update Model ในไฟล์ prisma.schema ให้เรียกใช้คำสั่ง
npx prisma generate
Seeding
นอกจากการสร้างโครงสร้างของ Database ด้วย Migration แล้วเรายังมี Seeding สำหรับการใส่ข้อมูลเริ่มต้น(Master Data)เข้าไปในฐานข้อมูล เพื่อให้ Application สามารถเริ่มต้นทำงานได้เลย
ในตัวอย่างนี้ให้ทำการสร้างไฟล์ prisma/seed.js
ขึ้นมาแลว้วทำการใส่ข้อมูลเริ่มต้นลงไป
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() {
await prisma.user.create({
data: {
name: 'John Doe',
email: 'john@example.com',
posts: {
create: { title: 'Hello World', content: 'My first post' },
},
},
});
}
main()
.then(() => prisma.$disconnect())
.catch(e => {
console.error(e);
prisma.$disconnect();
});
หลังจากนั้นเรียน Seed ขึ้นมาใช้งานด้วยคำสั่ง
node prisma/seed.js
หลังจากนั้นเมื่อคุณเข้าไปดูใน Table Users เราจะพบว่ามี User ที่ชื่อ John Doe อยู่ 1 Record
การใช้ Prisma ใน Next.js
ใน Next.js เราจะใช้ PrimaClient
ในการติดต่อกับฐานข้อมูล โดยที่เราจะสร้างไฟล์ lib/prisma.js
(หรือ .ts
ถ้าใช้ TypeScript) ขึ้นมาใหม่ เพื่อป้องกันปัญหาตอน hot reload จะสร้าง PrismaClient
ขึ้นมาใหม่เรื่อยๆ
// lib/prisma.js
import { PrismaClient } from '@prisma/client'
const globalForPrisma = global;
const prisma = globalForPrisma.prisma || new PrismaClient();
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
export default prisma;
การ Query ข้อมูล
ในตัวอย่างนี้เราจะสร้าง User API(/api/users
)ขึ้นมาเพื่อดึงข้อมูล Users ทั้งหมดออกมา
// app/api/users/route.ts
import prisma from '@/app/lib/prisma';
export default async function Get() {
const users = await prisma.user.findMany({
include: {
posts: true,
},
});
return new Response(JSON.stringify(posts), {
headers: {'Content-Type', 'application/json'},
status: 200
})
}
หลังจากนั้นเราจะนำข้อมูล Users ไปแสดงผลที่หน้า UI ด้วยคำสั่ง fetch
// app/users/page.tsx
"use client"
import { useEffect, useState } from 'react';
export default function Home() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch('/api/users')
.then(res => res.json())
.then(data => setUsers(data));
}, []);
return (
<div>
<h1>Users</h1>
{users.map(user => (
<div key={user.id}>
<strong>{user.name}</strong> - {user.email}
</div>
))}
</div>
);
}
เพียงเท่านี้เราก็สามารถนำข้อมูลในฐานข้อมูลออกไปแสดงผลที่หน้า UI ได้ง่ายๆ ด้วย Prisma
สรุปขั้นตอนการใช้ Prisma กับ Next.js
- สร้างโปรเจกต์ Next.js
- ติดตั้ง Prisma และ database adapter(ขึ้นอยู่กับ Database ที่เราใช้)
- สร้าง schema ใน
schema.prisma
- migrate database ด้วย
npx prisma migrate
- สร้าง
prisma/seed.js
เพื่อระบุข้อมูลตั้งต้น ุ6. Run Seed.js ด้วยnode prisma/seed.js
- Query ข้อมูลออกไปแสดงผลที่หน้า UI ได้เลย