Skip to main content
0

สรุปสั้น ๆ

เขียน Go ต่อกับฐานข้อมูล SQL ไม่รู้จะจัก GORM ไม่ได้แล้วว

เขียนโดย
Sirasit Boonklang (Aeff)
Tech and Coding Consultant

บทความนี้ตีพิมพ์ และ เผยแพร่เมื่อ 9 พฤษภาคม 2566

GORM คืออะไร

GORM คือ Library ของ ORM สำหรับใช้งานในภาษา Golang

แล้วเจ้า ORM เนี่ยคืออะไรอีก?

ORM คือ เทคนิคที่ช่วยให้เราสามารถแมปข้อมูลระหว่าง Relational Database กับภาษาโปรแกรมมิ่งที่เขียนแบบ OOP โดยจะทำให้เราไม่จำเป็นต้องเขียนคำสั่ง SQL เอง แต่จะเป็นการเขียนในรูปแบบคำสั่งของภาษาโปรแกรมมิ่งนั้น ๆ ได้เลย ทำให้ลดความซับซ้อนของการติดต่อหรือมี Interact กับฐานข้อมูล

ฟีเจอร์เด็ด ๆ ของเจ้า GORM

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 กันไปแล้วเรามาดูวิธีการใช้งานเบื้องต้นกันดีกว่าาาา

ตัวอย่างการใช้งาน GORM ต่อกับฐานข้อมูล MySQL

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")
	}
  • mysql.Open: เป็นการระบุว่าเรากำลังใช้ไดรเวอร์ MySQL เพื่อเชื่อมต่อกับฐานข้อมูล
  • &gorm.Config{}: สร้าง GORM Config ใหม่พร้อมค่า default
  • db, err := gorm.Open(…): เปิด Database Connection ใหม่โดยใช้ไดรเวอร์และ Configuration
  • if err != nil {…}: เป็นตัวเช็ค error

8. ก่อนที่เราจะใช้ User model ได้ เราต้องสร้างตารางในฐานข้อมูลก่อน โดยใช้ฟังก์ชัน AutoMigrate ของ GORM ฟังก์ชันนี้จะสร้างตารางสำหรับ User model โดยอัตโนมัติ

db.AutoMigrate(&User{})

9. เมื่อเราทำการต่อกับฐานข้อมูลเรียบร้อยแล้วต่อมาเรามาลองทำ CRUD Operation สำหรับการเพิ่มข้อมูล ดึงข้อมูล อัปเดตข้อมูล และลองลบข้อมูลในฐานข้อมูลด้วย Go กันครับ

Create Operation

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

Read Operation

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)

Update Operation

 

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)

Delete Operation

 

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 คืออะไร

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

  • app = Flask(name): ที่ ส่วนในการสร้าง Flask Instance เริ่มต้น
  • app.config[‘SECRET_KEY’] = ‘SECRET_KEY’ : แอตทริบิวต์ app.config เป็น dict ในการเก็บการ config ต่าง ๆ ของแอป จะตั้งค่าของตัวแปร config โดยใช้ SECRET_KEY เป็นสตริง ใช้เป็นคีย์ลับเพื่อเข้ารหัสคุกกี้และป้องกันการโจมตีต่างๆ เช่น การโจมตี CSRF
  • CONNECTION_STRING = “” : ตัวแปร CONNECTION_STRING คือ Connection String ที่ใช้เชื่อมต่อกับบัญชี Azure Blob Storage ค่าของสตริงนี้รวมถึง AccountName, AccountKey, และ EndpointSuffix
  • CONTAINER_NAME =””: คือ ชื่อคอนเทนเนอร์ในบัญชี Blob Storage ที่จะจัดเก็บไฟล์

ระบบฝึกทักษะ การเขียนโปรแกรม

ที่พร้อมตรวจผลงานคุณ 24 ชั่วโมง

  • โจทย์ปัญหากว่า 200 ข้อ ที่รอท้าทายคุณอยู่
  • รองรับ 9 ภาษาโปรแกรมหลัก ไม่ว่าจะ Java, Python, C ก็เขียนได้
  • ใช้งานได้ฟรี ! ครบ 20 ข้อขึ้นไป รับ Certificate ไปเลย !!
เข้าใช้งานระบบ DevLab ฟรี !เรียนรู้เพิ่มเติม

เรียนรู้ไอที “อัพสกิลเขียนโปรแกรม” จากตัวจริง
ปั้นให้คุณเป็น คนสายไอทีระดับมืออาชีพ

BorntoDev

Author BorntoDev

BorntoDev Co., Ltd.

More posts by BorntoDev

เราใช้คุกกี้เพื่อพัฒนาประสิทธิภาพ และประสบการณ์ที่ดีในการใช้เว็บไซต์ของคุณ คุณสามารถศึกษารายละเอียดได้ที่ นโยบายความเป็นส่วนตัว และสามารถจัดการความเป็นส่วนตัวเองได้ของคุณได้เองโดยคลิกที่ ตั้งค่า

ตั้งค่าความเป็นส่วนตัว

คุณสามารถเลือกการตั้งค่าคุกกี้โดยเปิด/ปิด คุกกี้ในแต่ละประเภทได้ตามความต้องการ ยกเว้น คุกกี้ที่จำเป็น

ยอมรับทั้งหมด
จัดการความเป็นส่วนตัว
  • คุกกี้ที่จำเป็น
    เปิดใช้งานตลอด

    ประเภทของคุกกี้มีความจำเป็นสำหรับการทำงานของเว็บไซต์ เพื่อให้คุณสามารถใช้ได้อย่างเป็นปกติ และเข้าชมเว็บไซต์ คุณไม่สามารถปิดการทำงานของคุกกี้นี้ในระบบเว็บไซต์ของเราได้
    รายละเอียดคุกกี้

  • คุกกี้สำหรับการติดตามทางการตลาด

    ประเภทของคุกกี้ที่มีความจำเป็นในการใช้งานเพื่อการวิเคราะห์ และ นำเสนอโปรโมชัน สินค้า รวมถึงหลักสูตรฟรี และ สิทธิพิเศษต่าง ๆ คุณสามารถเลือกปิดคุกกี้ประเภทนี้ได้โดยไม่ส่งผลต่อการทำงานหลัก เว้นแต่การนำเสนอโปรโมชันที่อาจไม่ตรงกับความต้องการ
    รายละเอียดคุกกี้

บันทึกการตั้งค่า