สรุปสั้น ๆ
เขียน Go ต่อกับฐานข้อมูล SQL ไม่รู้จะจัก GORM ไม่ได้แล้วว
เขียน Go ต่อกับฐานข้อมูล SQL ไม่รู้จะจัก GORM ไม่ได้แล้วว
เขียนโดย
Sirasit Boonklang (Aeff)
Tech and Coding Consultant
บทความนี้ตีพิมพ์ และ เผยแพร่เมื่อ 9 พฤษภาคม 2566
GORM คือ Library ของ ORM สำหรับใช้งานในภาษา Golang
ORM คือ เทคนิคที่ช่วยให้เราสามารถแมปข้อมูลระหว่าง Relational Database กับภาษาโปรแกรมมิ่งที่เขียนแบบ OOP โดยจะทำให้เราไม่จำเป็นต้องเขียนคำสั่ง SQL เอง แต่จะเป็นการเขียนในรูปแบบคำสั่งของภาษาโปรแกรมมิ่งนั้น ๆ ได้เลย ทำให้ลดความซับซ้อนของการติดต่อหรือมี Interact กับฐานข้อมูล
1. Associations: GORM รองรับการเชื่อมโยงประเภทต่าง ๆ เช่น has one, have many, belongs to, many to many, polymorphism และ single-table inheritance สิ่งนี้ทำให้คุณสามารถกำหนดและจัดการความสัมพันธ์ระหว่างตารางฐานข้อมูลต่าง ๆ ได้อย่างง่ายดาย
2. Hooks: GORM จัดเตรียม hooks สำหรับ ก่อนและหลัง Create/Save/Update/Delete/Find operation ทำให้คุณสามารถ custom logic ได้
3.Eager loading: GORM รองรับ eager loading โดยใช้ Method Preload และ Joins ทำให้ลดจำนวนการดึงข้อมูลเฉพาะที่เกี่ยวข้อง
4.Transactions: GORM รองรับ transaction และ nested transaction ช่วยให้มั่นใจได้ถึงความสอดคล้องและความสมบูรณ์ของข้อมูลเมื่อมีการใช้ฐานข้อมูลหลาย operation
5. Context and Prepared Statement Mode รองรับ Context และโหมดคำสั่งที่เตรียมไว้ ทำให้ลดความเสี่ยงของการโจมตี SQL Injection
6. Batch Insert และ FindInBatches: GORM มีฟังก์ชันการแทรกและการค้นหาใน Batch ซึ่งช่วยปรับปรุงประสิทธิภาพการทำงานเมื่อทำงานกับข้อมูลจำนวนมาก
7. SQL Builder: ตัวสร้าง SQL ที่รองรับ Upsert, Locking, Optimizer/Index/Comment Hints, Argument ที่มีชื่อ และ SubQuery
8.Composite Primary Key: GORM รองรับ คีย์หลักแบบผสม Index และ constraint ทำให้คุณสามารถกำหนด schema ซับซ้อนมากขึ้นและรับประกันความสมบูรณ์ของข้อมูลได้
9.Auto Migrations: ฟังก์ชันการย้ายข้อมูลอัตโนมัติที่สามารถสร้างตารางฐานข้อมูลแบบออโต้และอัปเดต schema ได้ตามใจต้องการ
10.Logger: GORM เค้ามี ****Logger**** ที่สามารถช่วยให้เรา Debug และเพิ่มประสิทธิภาพการดึงข้อมูลได้
11.API, Plugin และ Extension: มี API, Plugin และ Extension ให้ใช้เป็นกระบุง (เยอะมาก) ทำให้สามารถเพิ่มฟังก์ชันการทำงานเพิ่มเติมหรือต่อกับเครื่องมืออื่น ๆ ได้อีกมากมาย
12.Developer Friendly: เหล่าเดฟอย่างเรา ๆ จะยิ้มง่ายเพราะมันใช้ได้ง่าย Docs ก็อ่านไม่ยาก ใครอยากอ่านเพิ่มเติมสามารถไปตำได้ที่ [GORM Guides | GORM – The fantastic ORM library for Golang, aims to be developer friendly.](https://gorm.io/docs/)
9.Auto Migrations: ฟังก์ชันการย้ายข้อมูลอัตโนมัติที่สามารถสร้างตารางฐานข้อมูลแบบออโต้และอัปเดต schema ได้ตามใจต้องการ
10.Logger: GORM เค้ามี Logger ที่สามารถช่วยให้เรา Debug และเพิ่มประสิทธิภาพการดึงข้อมูลได้
11.API, Plugin และ Extension: มี API, Plugin และ Extension ให้ใช้เป็นกระบุง (เยอะมาก) ทำให้สามารถเพิ่มฟังก์ชันการทำงานเพิ่มเติมหรือต่อกับเครื่องมืออื่น ๆ ได้อีกมากมาย
12.Developer Friendly: เหล่าเดฟอย่างเรา ๆ จะยิ้มง่ายเพราะมันใช้ได้ง่าย Docs ก็อ่านไม่ยาก ใครอยากอ่านเพิ่มเติมสามารถไปตำได้ที่ GORM Guides | GORM – The fantastic ORM library for Golang, aims to be developer friendly.
เมื่อเราได้รู้จักกับ GORM กันไปแล้วเรามาดูวิธีการใช้งานเบื้องต้นกันดีกว่าาาา
1.เริ่มจากสร้างโฟลเดอร์โปรเจกต์ด้วยคำสั่ง md <ชื่อโฟลเดอร์> แล้วทำการ cd <ชื่อโฟลเดอร์> หลังจากนั้นเปิดโปรแกรม VS Code ด้วยคำสั่ง code .
2. เริ่มจากการสร้าง go mod ของโปรเจกต์ด้วยคำสั่ง go mod init <github repo>/ชื่อโปรเจกต์
3. ติดตั้ง GORM ด้วยคำสั่ง go get -u gorm.io/gorm
4. สร้างไฟล์ main.go เริ่มต้นประกาศ package เริ่มต้นเป็น main สร้างฟังก์ชัน main ให้เรียบร้อย และทำการ import “gorm.io/gorm” มาด้วยนะ
package main
import (
"gorm.io/gorm"
)
func main() {
}
5. ต่อมากำหนดโครงสร้างของข้อมูล ชื่อตารางและฟิลด์ต่าง ๆ (คอลัมน์ของตาราง) ว่ามีอะไรบ้างโดยใน Go เวลาที่เขียนเป็น ORM เราจะเขียนอยู่ในรูปแบบ Struct นะ
ในตัวอย่างนี้ เราได้กำหนดโครงสร้างของตาราง `User` ด้วยฟิลด์ ID, Name, Email, Age, CreateAt และ UpdatedAt และเรามีการใช้ gorm ในการกำหนดข้อจำกัดสำหรับแต่ละฟิลด์
type User struct {
ID uint `gorm:"primarykey"`
Name string `gorm:"not null"`
Email string `gorm:"unique"`
Age int
CreatedAt time.Time
UpdatedAt time.Time
}
6. ต่อมาเราก็มาทำการเชื่อมต่อกับฐานข้อมูลโดยตัวอย่างนี้ผมจะใช้เป็น MySQL แต่ไม่ใช่ว่า GORM จะต่อได้แค่ MySQL นะ มันยังต่อกับ PostgreSQL, SQLite, SQL Server, และ TiDB ได้อีกด้วย โดยในส่วนของการเรียกใช้งาน MySQL จะต้องทำการติดตั้งด้วยคำสั่ง go get gorm.io/driver/mysql
และเรียกใช้งานในส่วนของ import ด้วยนะครับ
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
7. การสร้าง GORM Database Connection เพื่อเชื่อมต่อกับฐานข้อมูล MySQL
db, err := gorm.Open(mysql.Open("username:password@tcp(127.0.0.1:3306)/ชื่อฐานข้อมูล?charset=utf8mb4&parseTime=True&loc=Local"), &gorm.Config{})
if err != nil {
panic("failed to connect to database")
}
8. ก่อนที่เราจะใช้ User model ได้ เราต้องสร้างตารางในฐานข้อมูลก่อน โดยใช้ฟังก์ชัน AutoMigrate ของ GORM ฟังก์ชันนี้จะสร้างตารางสำหรับ User model โดยอัตโนมัติ
db.AutoMigrate(&User{})
9. เมื่อเราทำการต่อกับฐานข้อมูลเรียบร้อยแล้วต่อมาเรามาลองทำ CRUD Operation สำหรับการเพิ่มข้อมูล ดึงข้อมูล อัปเดตข้อมูล และลองลบข้อมูลในฐานข้อมูลด้วย Go กันครับ
10. การเพิ่มข้อมูลไปยังฐานข้อมูล เราสามารถสร้าง User คนใหม่เข้าไปได้โดยใช้ฟังก์ชัน Create ที่มากับ GORM ได้เลย เช่น เราจะลองสร้าง User ชื่อ Sirasit, อีเมลคือ sirasit@example.com และอายุเป็น 25 ปี แล้วใช้ฟังก์ชัน Create จะเขียนได้ตามตัวอย่างด้านล่าง
user := User{
Name: "Sirasit",
Email: "sirasit@example.com",
Age: 25,
}
result := db.Create(&user)
if result.Error != nil {
panic("failed to create user")
}
ตัวอย่างโค้ดแบบเต็ม ๆ นะครับ
package main
import (
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type User struct {
ID uint `gorm:"primarykey"`
Name string `gorm:"not null"`
Email string `gorm:"unique"`
Age int
CreatedAt time.Time
UpdatedAt time.Time
}
func main() {
db, err := gorm.Open(mysql.Open("ชื่อผู้ใช้:รหัสผ่าน(127.0.0.1:3306)/ชื่อฐานข้อมูล?charset=utf8mb4&parseTime=True&loc=Local"), &gorm.Config{})
if err != nil {
panic("failed to connect to database")
}
db.AutoMigrate(&User{})
user := User{
Name: "Sirasit",
Email: "sirasit@example.com",
Age: 25,
}
result := db.Create(&user)
if result.Error != nil {
panic("failed to create user")
}
}
ผลลัพธ์ที่ได้จากการรันโปรแกรมจะเห็นได้ว่ามีข้อมูลที่เราได้ทำการเพิ่มเข้าไป ไปอยู่ในฐานข้อมูลเป็นที่เรียบร้อยแล้วนะครับ สำหรับในตอนนี้ผมจะใช้เครื่องมือที่ชื่อว่า MySQL Workbench ในการเรียกดูข้อมูลนะครับ
สำหรับใครที่อยากดูวิธีการใช้งาน MySQL Workbench สามารถดูขั้นตอนการใช้งานร่วมกับภาษา Go ได้ที่ https://youtu.be/fjEB75Xotxc?t=12764
11. ในการอ่านข้อมูลจากฐานข้อมูลเราสามารถใช้ฟังก์ชัน Find และ First ได้ โดยเมื่อเราได้ทำการดึงข้อมูลมาแล้วเราจะทำการเช็ค Error และใช้ for loop ในการดึงค่าของข้อมูลแต่ละตัวออกมาแสดง
var users []User
result := db.Find(&users)
if result.Error != nil {
panic("Failed to find users")
}
for _, user := range users {
fmt.Printf("ID: %d, Name: %s, Email: %s, Age: %d\n", user.ID, user.Name, user.Email)
}
หรือหากต้องการดึงเฉพาะ ID นั้น ๆ เราก็สามารถใช้ฟังก์ชัน First หรือ Find และผ่านค่าของตัวแปรชื่อตารางและ ID เข้าไปได้
var user User
result := db.Find(&user, 1) // Find the user with ID 1
if result.Error != nil {
panic(result.Error)
}
fmt.Println(user)
12. ในการอัปเดตเราสามารถใช้ Method Model() และ Updates() ในการอัปเดตข้อมูลได้ โดยในตัวอย่างนี้ จะใช้ db.First() เพื่อค้นหา user ที่มี ID เป็น 1 แล้วก็ใช้ db.Model().Updates() เพื่ออัปเดต Name ให้เป็น “Sirasit Boonklang” แทน และในตัวอย่างโค้ดนี้ผมก็มีการเช็ค Error และนำข้อมูล ID ที่มีการอัปเดตมาแสดงด้วย
var user User
db.First(&user, 1)
db.Model(&user).Updates(User{Name: "Sirasit Boonklang"})
result := db.First(&user, 1)
if result.Error != nil {
panic(result.Error)
}
fmt.Println(user)
13. สำหรับการลบข้อมูลในฐานข้อมูลเราสามารถใช้ Method Delete ของ GORM ได้เลยโดยใช้คำสั่ง db.Delete()
var user User
result := db.Find(&user, 1)
if result.Error != nil {
panic(result.Error)
}
result = db.Delete(&user)
if result.Error != nil {
panic(result.Error)
}
และแล้วตอนนี้เราก็ได้เรียนรู้พื้นฐานเบื้องต้นเกี่ยวกับ GORM ไปแล้วนะครับ แต่เรายังติดในส่วนของการใช้ gorm.Model กันนะครับ เดี๋ยวผมจะพาไปดูว่าการใช้ gorm.Model มันช่วยเรายังไงได้บ้างไปดูกันครับ
gorm.Model เป็น Struct ที่มากับเจ้า GORM Lib ตัวนี้ โดย gorm.Model จะมาพร้อมกับฟิลด์ ID, CreateAt, UpdateAt, DeletedAt ซึ่งปกติแล้วฐานข้อมูลส่วนใหญ่ก็จะมีฟิลด์เหล่านี้อยู่
// gorm.Model definition
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
โดย ID จะเป็นฟิลด์ที่เป็น Primary Key ของโมเดล, CreateAt เอาไว้เก็บว่าเวลาที่ข้อมูลถูกสร้างขึ้นมา, UpdateAt สำหรับเก็บเวลาที่มีการอัปเดตล่าสุด และฟิลด์สุดท้ายคือ DeletedAt เป็นฟิลด์ที่จะบันทึกเวลาและทำเครื่องหมายว่าลบแล้วนั่นเองเป็นแบบ Soft Delete
เมื่อเราจะใช้ gorm.Model เราแค่แปะคำสั่งไว้ใน Struct ของตารางข้อมูลเรา เพียงเท่านี้เราก็จะได้ฟิลด์ของ gorm.Model มาใช้เรียบร้อยแล้ววว
type User struct {
gorm.Model
Name string `gorm:"not null"`
Email string `gorm:"unique"`
Age int
}
เป็นยังไงบ้างครับการใช้งาน GORM ไม่ยากเลยใช่มั้ยครับ หากเพื่อน ๆ อยากฝึกสกิลเพิ่มเติมเกี่ยวกับการใช้งาน GORM อ่านเพิ่มเติมได้จาก Docs ในลิงก์นี้ได้เลยนะครับ GORM Guides | GORM – The fantastic ORM library for Golang, aims to be developer friendly.
และหากอยากรู้ว่าถ้าเราไม่ใช้ GORM ทำ CRUD แบบปกติจาก Standard Library เลยมีวิธีการยังไงบ้างและแตกต่างกันยังไงสามารถดูตัวอย่างการทำได้ที่ (572) สอนทำ CRUD ด้วย Golang แบบไม่เกรงใจใคร ! – YouTube
แนะนำสำหรับคุณ
เราใช้คุกกี้เพื่อพัฒนาประสิทธิภาพ และประสบการณ์ที่ดีในการใช้เว็บไซต์ของคุณ คุณสามารถศึกษารายละเอียดได้ที่ นโยบายความเป็นส่วนตัว และสามารถจัดการความเป็นส่วนตัวเองได้ของคุณได้เองโดยคลิกที่ ตั้งค่า