จัดการ Database Model บน Go ง่ายๆ ด้วย Ent Framework !!!

Nipat Udomwongwattana
Sirisoft
Published in
5 min readMay 27, 2022

สวัสดีครับ วันนี้ผมจะมาสอนวิธีการจัดการ Database model ของ Go ด้วย Ent Framework กันครับ โดยเรามาเริ่มจากทำความรู้จัก Ent กันก่อนดีกว่า

Ent เป็น Framework ของ Golang ที่ช่วยในการสร้างและจัดการ application ที่มี Data Model ขนาดใหญ่ โดยจุดเด่นของ Ent ก็คือ

  • สามารถสร้าง schema ได้ด้วยภาษา Go
  • schema ที่ถูกสร้างขึ้น จะอยู่ในรูปแบบของ Graph Structure
  • เขียน Query ง่าย เพราะมี function รองรับสำหรับ CRUD
  • เพราะ Schema ถูกเก็บอยู่ในรูปแบบของ Code ภาษา Go จึงง่ายต่อการแก้ไข

หลังจากเราได้รู้จัก Ent กันไปแล้ว ต่อไปจะเป็นเนื้อหาในครั้งนี้กันครับ โดยในครั้งนี้เรื่องที่ผมจะสอน ประกอบไปด้วย

  • การ Create Schema
  • Field
  • Edge (Relation)
  • CRUD API

ทั้งหมด 4 หัวข้อด้วยกัน ถ้าพร้อมแล้ว เรามาเริ่มกันเลยครับ

Prerequisite

  • พื้นฐาน ภาษา Go
  • Database (ในครั้งนี้ผมจะใช้เป็น postgresql นะครับ)

Installation

เริ่มจากทำการ setup go module ของ project ดังนี้

go mod init <project> 

ตามด้วยติดตั้ง Ent

go get -d entgo.io/ent/cmd/ent

Create Schema

หลังจากติดตั้งเสร็จแล้ว เรามาเริ่มสร้าง Schema กัน ด้วยคำสั่ง

go run entgo.io/ent/cmd/ent init <schema name>

โดยในตัวอย่างจะลองสร้าง Schema User ดูนะครับ

go run entgo.io/ent/cmd/ent init User

Command นี้จะทำการสร้าง schema User ที่ directory <project>/ent/schema/
ดังรูป

Schema User

โดยหน้าตาข้างในไฟล์จะเป็นไปตาม code ด้านล่างนี้

ก่อนที่จะพูดเรื่อง Field เรามาลองเพิ่ม Field ดูใน Schema นี้ก่อน โดยในตัวอย่างข้างล่างผมจะลองเพิ่ม Field ชื่อ name และ age ดู

หลังจากลองเพิ่ม Field ดูแล้ว ต่อไปก็พิมพ์คำสั่งตามด้านล่าง

go generate ./ent

เมื่อพิมพ์คำสั่งนี้ ent จะทำการ generate ไฟล์ที่เก็บฟังก์ชันสำหรับ CRUD ของ Schema นั้นไว้ ดังรูปด้านล่าง

จากนั้นเรามาลองสร้าง Ent Client สำหรับจัดการกับ Schema ตามตัวอย่างด้านล่างนี้

หลังจากสร้าง Client แล้วเรามาลองสร้าง Entity ให้ Schema User กัน

ด้านบนจะเป็นตัวอย่างการเพิ่ม Entity ของ Schema User โดยการกำหนด ชื่อของ User เป็น “Somsak” และ อายุเป็น “30”

จากนั้นก็ลอง Query ดูด้วย Method Query และใช้ Where ในการกำหนดเงื่อนไขว่า ชื่อของ User ต้องชื่อ “Somsak”

โดยรูปด้านล่างนี้คือผลลัพธ์ที่ได้

หลังจากดูตัวอย่างไปแล้ว ต่อไปเรามาดูรายละเอียดกันดีกว่า

Field

Field ใน Schema เปรียบเสมือน Column ในDatabaseโดยเราสามารถเพิ่ม Field ใน Schema ได้ผ่านทาง Method Fields ของ Schema นั้นๆ

ในตัวอย่างนี้จะทำการเพิ่ม Field ใน Schema User ได้แก่ firstname,lastname และ age

Type

Type ที่ Framework นี้ support ได้แก่

  • numeric type ต่างๆ เช่น int, uint8, float64 etc.
  • string
  • bool
  • time.Time
  • UUID
  • []byte (เฉพาะ SQL)
  • JSON (เฉพาะ SQL)
  • ENUM (เฉพาะ SQL)
  • Other (เฉพาะ SQL)

ID Field

ID เป็น default field ของทุก schema ไม่จำเป็นต้องเพิ่ม Field นี้เข้าไป โดยเราสามารถ Config ID Field ได้

ในตัวอย่างด้านบนเป็นการ Config ให้ field id ของ user มี type เป็น uuid

Database Type

ent จะมีการกำหนด Default Database Type ให้ทุก Type ของ Field ตามชนิดของ Database ไว้อยู่แล้ว แต่เราสามารถกำหนด Database Typeให้แต่ละ Field เองได้ด้วย Method SchemaType

โดยในตัวอย่างจะเป็นการเปลี่ยน type ของ column age ใน database postgres เป็น เป็น numeric แทน type เดิมที่เป็น int8

Go Type

นอกจาก Database type เราสามารถใช้ Method GoType เพื่อกำหนด type ของ go ในแต่ละ Field เองได้

ตัวอย่างนี้เป็นการเปลี่ยน type ของ lastname ที่เดิมเป็น string ให้เป็น sql.NullString แทน ซึ่งทำให้กรณีที่จะจัดการ Field นี้ต้องใช้ type เป็น lastname แทน แบบนี้

Default Value

Method Default และ UpdateDefault สามารถใช้กำหนดค่า Default ของ Field ได้เพื่อเป็นการกำหนดค่านั้นอัตโนมัติ ทุกครั้งที่มีการ Create หรือ Update Entity

ซึ่งตัวอย่างนี้เป็นการกำหนดค่า Default ของ field update_at ให้เป็นเวลาปัจจุบันตอนที่มีการ Create หรือ Update

Optional

โดยปกติแล้ว Field ทุก Field ใน Schema จะถูกกำหนดเป็น required field ซึ่งเราสามารถเปลี่ยนเป็น Optional Field ได้ด้วย Optional Method

Storage Key

Storage Key ใช้สำหรับกำหนด Column Name ใน Database สำหรับ Field นั้น

ตัวอย่างนี้เป็นการเปลี่ยนชื่อ Column ของ id เป็น userid แทน

เนื้อหาในเรื่องของ Field ก็จบเท่านี้ครับ ต่อไปเป็นเรื่องของ Edge

Edge

Edge คือ Relation ระหว่าง Schema โดย Method ที่ใช้ในการกำหนด Edge คือ edge.To และ edge.From โดย edge.To จะเป็นการสร้าง Relation ส่วน edge.From จะเป็นการสร้าง back-reference สำหรับใช้อ้างถึง Relation

ก่อนอื่นก็สร้าง Schema เพิ่มอีก 1 Schema

go run entgo.io/ent/cmd/ent init Pet

จากนั้นเพิ่ม Edge ให้กับ User และ Pet

จากตัวอย่างนี้ เป็นการสร้าง Edge pets ขึ้นที่ Schema User และสร้าง back-reference ชื่อ owner ที่ Schema Pet เพื่อให้โยงไปถึง User จาก Pet ได้

ซึ่ง Method Ref เป็นตัวกำหนด Edge ที่จะใช้เชื่อมโยงด้วย

ส่วน Method Unique จะเป็นตัวกำหนดรูปแบบของ Relation ซึ่งต่อไปจะเป็นตัวอย่างการกำหนด Relation รูปแบบต่างๆ

One-to-One

สร้าง Schema ใหม่ ชื่อ Card และเพิ่ม Edge ไปใน Schema User และ Card

ในการสร้าง Relation แบบ One-to-One ทำได้โดยเพิ่ม Method Unique ที่ทั้งสอง Schema เพื่อกำหนดให้แต่ละ Entity ของ Schema ไม่สามารถมี Edge ซ้ำกันได้

จากนั้นลองเพิ่มข้อมูล แล้วก็ Query ดู

ในตัวอย่างนี้ทำอะไรไปบ้าง ?

เริ่มจาก Create Entity ของ User แล้วก็ Card ขึ้นมาอย่างละ 1 โดยให้ User นี้เป็นเจ้าของ Card จากนั้นก็ Query ข้อมูล โดย Query Card ผ่าน User ด้วย Method QueryCard และ Query User ผ่าน Card ด้วย Method QueryOwner

ผลลัพธ์ที่ได้ ก็จะเป็นไปตามรูปด้านล่าง

One-to-Many

ความสัมพันธ์แบบ One-to-Many ทำได้โดยเพิ่ม Unique เข้าไปในฝั่งที่ต้องการให้เป็น Many

จากตัวอย่างนี้เพิ่ม Method Unique() ที่ owner ของ Pet ทำให้ Pet แต่ละตัวมีเจ้าของได้คนเดียว

จากตัวอย่างเป็นการสร้าง Pet มาสองตัวแล้วก็สร้าง User พร้อมกับเพิ่ม Pet เข้าไป จากนั้นก็ลอง Query และ Print ค่าออกมาดู

ผลลัพธ์ที่ได้ :

Many-to-Many

สร้าง Schema ชื่อ Group ขึ้นมาใหม่

วิธีสร้าง Relation แบบ Many-to-Many คือไม่ต้องใช้ Method Unique ทั้งสองฝั่งเลย

ตัวอย่างนี้เป็นการสร้าง Group และ User ขึ้นมา อย่างละ 2 และลอง Query Group ของแต่ละ User ดู

ผลลัพธ์ที่ได้ :

การสร้าง Relation แบบต่างๆก็จบลงเท่านี้ครับ ต่อไปเป็นเรื่องของ CRUD API

CRUD API

จากตัวอย่างหลายๆอันข้างบน เราก็ได้เห็นการใช้ฟังก์ชัน CRUD ไปแล้วบ้างนะครับ ในหัวข้อนี้เราจะมาพูดถึงวิธีการเขียน CRUD กัน ซึ่งจาก Command ด้านล่าง

go generate ./ent

ent จะทำการ generate method ต่างๆในการทำ CRUD มาให้ซึ่ง method ในแต่ละ Schema ก็จะแตกต่างกันตาม Field หรือ edge ใน Schema นั้นๆ

เรามาดูตัวอย่างการใช้ CRUD API กัน โดยข้างล่างนี้จะเป็นข้อมูล Schema ที่ใช้ในตัวอย่างนี้

Create

การ Create ทำได้โดยใช้ method create ของ schema นั้นๆแล้วตามด้วย method สำหรับกำหนดค่า Field ต่างๆใน Schema แล้วจบด้วย method Save หรือ SaveX ซึ่ง Save จะ return error ส่วน SaveX จะ panic ถ้ามี error

ผลลัพธ์ที่ได้ :

Update

Method ที่ใช้ Update มีสองแบบ คือ UpdateOne และ Update โดย UpdateOne จะคืนค่าเป็น Schema นั้น ส่วน Update จะคืนค่าเป็นจำนวน row ที่ถูก update

Query

เราสามารถ Query ได้หลายแบบไม่ว่าจะเป็น Query ผ่าน Schema โดยตรงหรือ Query ผ่าน Edge ของ Schema อื่น และสามารถเพิ่มเงื่อนไขในการ Query ได้ผ่าน Method Where

จากตัวอย่างจะเห็นว่าถ้า Query Pet แบบธรรมดาจะไม่สามารถดูข้อมูลของ Owner ได้ต้องเพิ่ม Method With เข้าไปด้วยจึงจะสามารถดูข้อมูลผ่าน Edge Owner ได้

Delete

ตัวอย่างนี้คือการลบ User แบบ 1 User และนี่คือผลลัพธ์ที่ได้

ก่อนลบ:

หลังลบ:

ส่วนตัวอย่างนี้คือการลบด้วยเงื่อนไข

เป็นการลบ User ที่มีอายุมากกว่าหรือเท่ากับ 30 โดย ผลลัพธ์ที่ได้

ก่อนลบ:

หลังลบ:

ครับ ก็จบไปแล้วนะครับสำหรับวิธีการจัดการ Database Model ด้วย Ent ซึ่งเนื้อหานี้เป็นเพียงพื้นฐานของการใช้งาน Framework นี้เท่านั้น ถ้าต้องการที่จะศึกษาเพิ่มเติมสามารถเข้าไปศึกษาได้ที่

ส่วน link นี้ เป็น git ที่รวมตัวอย่าง code ที่ใช้ในบทเรียนนี้

สามารถติดตามบทความและข่าวสารอื่นๆได้ที่ https://www.facebook.com/sirisoft และเพื่อนๆคนไหนสนใจอยากมา Dev ด้วยกันสามารถสมัครและทักสอบถาม HR กันมาได้นะครับ https://lin.ee/ms8vit4 ขอบคุณครับ

--

--