Prisma
Prisma คือ ORM (Object-Relational Mapping) ของฝั่ง Node.js/TypeScript ที่นิยมที่สุดตัวหนึ่ง จุดเด่นคือ type-safe เต็มรูปแบบ — auto-generate TypeScript client จาก schema ทำให้ query ทุกอันมี autocomplete + ตรวจ type ตอน compile
เทียบ Java: Prisma ทำหน้าที่เหมือน Hibernate/JPA แต่ปรัชญาต่างกันชัด — Hibernate ใช้
@Entityบน class แล้ว map กลับไปตาราง ส่วน Prisma แยก schema ออกมาเป็น ไฟล์ภาษากลาง (schema.prisma) ไฟล์เดียว เป็น single source of truth แล้ว generate code ออกมา ไม่ใช่เขียน entity class เอง
โครงสร้างการทำงาน
- นิยามตารางใน
schema.prisma(model+@attribute) prisma migrate dev→ สร้าง migration + อัปเดตตารางจริงprisma generate→ สร้าง Prisma Client (โค้ด TypeScript ที่ใช้ query)- import client มา query ในโค้ด
model User {
id Int @id @default(autoincrement())
email String @unique
password String
todos Todo[] // ความสัมพันธ์ 1—*
}
model Todo {
id Int @id @default(autoincrement())
title String
userId Int
user User @relation(fields: [userId], references: [id])
}Query หลัก ๆ
create / findMany / findUnique / findFirst / update / delete
findUnique— หาด้วย field ที่ unique (เช่น id, email) เท่านั้นfindFirst— หาแถวแรกที่ตรงเงื่อนไขทั่วไป (ใช้กรองid + userIdพร้อมกันเพื่อกันเห็นของคนอื่น)- relation —
Todo.userId+@relation, ฝั่งUser.todos Todo[](1—*)
Prisma 7 — จุดที่ต่างจากเวอร์ชันเก่า (และทำให้ติดบั๊ก)
Prisma 7 เปลี่ยนสถาปัตยกรรมหลายอย่างจน config เดิมใช้ไม่ได้:
- ใช้ driver adapter — ต้องต่อ DB ผ่าน adapter โดยตรง เช่น
@prisma/adapter-better-sqlite3(เดิม Prisma จัดการ connection ให้เอง) - ไม่อ่าน
.envให้อัตโนมัติ ในบาง flow → ต้องส่ง connection url เองผ่าน@nestjs/config(ConfigService) - เป็น ESM-first → ชนกับโปรเจกต์ที่ build เป็น CommonJS (
exports is not defined) แก้ด้วยmoduleFormat = "cjs"ใน schema - generated client + build layout ต้องจัดเอง (ย้าย generated เข้า
src/, excludeprisma.config.ts)
นี่คือ “ภาษีของ bleeding edge” — Prisma 7 ยังใหม่ ทำให้ tutorial เก่า ๆ ใช้ไม่ได้ ต้องอ่าน migration guide จริง
ในบริบท NestJS
- ห่อ
PrismaClientไว้ในPrismaServiceที่implements OnModuleInit, OnModuleDestroyเพื่อconnect()/disconnect()ตาม lifecycle ของ Nest - ตั้ง
PrismaModuleเป็น@Global()→ service อื่น injectPrismaServiceได้โดยไม่ต้อง import ซ้ำ
Key Points
- Prisma = ORM แบบ type-safe + schema-first (single source of truth ในไฟล์
.prisma) - ต่างจาก Hibernate: แยก schema เป็นไฟล์กลาง + generate client แทนเขียน entity class
- Flow: เขียน schema →
migrate dev→generate→ query - Prisma 7 ใช้ driver adapter + ESM-first → เป็นต้นเหตุบั๊กตอน setup กับ NestJS (CommonJS)
findFirst+ เงื่อนไขuserId= trick ทำ ownership scoping
Related
- NestJS — framework ที่ใช้ Prisma ในโปรเจกต์นี้
- ORM — แนวคิดที่ Prisma เป็นหนึ่งในนั้น
- Database Engines / SQLite — DB ปลายทาง
- NestJS PoC Todo - Learning Notes — source สรุปการเรียน