Sử dụng Gorm trong Go
Trong bài viết trước, mình đã giới thiệu với các bạn về cách sử dụng Fiber – một web framework mạnh mẽ và linh hoạt trong Go. Tiếp nối chuỗi seri về Golang, hôm nay mình sẽ mang đến cho các bạn một thư viện rất phổ biến và gần như không thể thiếu khi làm việc với cơ sở dữ liệu trong Go: GORM. Đây là một thư viện ORM (Object Relational Mapping) mạnh mẽ, giúp đơn giản hóa quá trình thao tác với database và được cộng đồng Golang sử dụng rộng rãi
1.GORM là gì?
GORM là viết tắt của Go Object Relational Mapping.
- Giúp ánh xạ các struct trong Go với các bảng trong cơ sở dữ liệu (MySQL, PostgreSQL, SQLite, SQL Server, v.v.)
- Hỗ trợ các thao tác CRUD (Create, Read, Update, Delete) đơn giản và linh hoạt.
- Hỗ trợ quan hệ giữa các bảng: 1-1, 1-n, n-n.
- Tích hợp sẵn các tính năng nâng cao như migrations, hooks, transactions, preload, eager/lazy loading...
2. Cài đặt GORM
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
Ngoài ra, chúng ta có thể sử dụng các driver khác như postgres, sqlite.
3. Cách sử dụng cơ bản
3.1 Kết nối với CSDL
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
)
func main() {
dsn := "username:password@tcp(127.0.0.1:3306)/your_db?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal("failed to connect database")
}
// DB đã sẵn sàng sử dụng
}
3.2 Định nghĩa model (struct)
type User struct {
ID uint `gorm:"primaryKey"`
Name string
Email string
}
3.3 Tự động tạo bảng (Auto migration)
db.AutoMigrate(&User{})
3.4 Các thao tác CRUD
Tạo mới
db.Create(&User{Name: "Alice", Email: "alice@example.com"})
Đọc dữ liệu
var user User
db.First(&user, 1) // Find by with id
db.First(&user, "email = ?", "alice@example.com") // Find by with email
Cập nhật dữ liệu
db.Model(&user).Update("Name", "Alice Updated")
Xoá dữ liệu
db.Delete(&user)
4. Một số tính năng nâng cao
4.1 Preload (Eager loading)
Bây giờ, mình sẽ cho một user có nhiều bài viết:
type User struct {
ID uint
Name string
Posts []Post
}
type Post struct {
ID uint
Title string
Content string
UserID uint
}
Dùng Preload để lấy cả user và post cùng lúc
var user User
db.Preload("Posts").First(&user)
4.2 Hooks (Callbacks)
Bạn có thể thêm logic tự động chạy trước/sau khi thao tác CSDL:
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
u.Name = strings.ToUpper(u.Name)
return
}
Các hooks phổ biến: BeforeCreate, AfterCreate, BeforeUpdate, AfterDelete,...
4.3 Soft Delete
type User struct {
gorm.Model // bao gồm trường DeletedAt
Name string
}
Khi gọi db.Delete(&user), bản ghi không bị xóa vĩnh viễn, chỉ được đánh dấu trong trường deleted_at
4.4 Select cụ thể trường (Column Selection)
db.Select("name", "email").Find(&users)
4.5 Transactions
err := db.Transaction(func(tx *gorm.DB) error {
if err := tx.Create(&User{Name: "A"}).Error; err != nil {
return err
}
if err := tx.Create(&User{Name: "B"}).Error; err != nil {
return err
}
return nil
})
Được sử dụng để đảm bảo tính toàn vẹn của dữ liệu. Giao dịch đảm bảo rằng một loạt thao tác cơ sở dữ liệu hoặc hoàn tất tất cả, hoặc không thao tác nào được thực hiện nếu có lỗi xảy ra.
4.6 Scopes (Reusable query logic)
func ActiveUsers(db *gorm.DB) *gorm.DB {
return db.Where("active = ?", true)
}
db.Scopes(ActiveUsers).Find(&users)
4.7 Custom SQL / Raw Queries
Khi bạn cần linh hoạt hơn trong query:
db.Raw("SELECT name FROM users WHERE id = ?", 1).Scan(&result)
4.8 Migration nâng cao
Bạn có thể tùy chỉnh cách tạo bảng:
db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{})
4.9 Index, Unique, Constraints
type User struct {
Email string `gorm:"uniqueIndex"`
Age int `gorm:"index"`
}
5.Tổng kết
GORM là một công cụ ORM mạnh mẽ và linh hoạt trong hệ sinh thái Go, giúp đơn giản hóa việc tương tác với cơ sở dữ liệu, đồng thời giữ được hiệu suất và khả năng mở rộng cao trong các ứng dụng thực tế. Hy vọng sau bài viết này, sẽ giúp các bạn làm việc với database trong Go một cách dễ dàng hơn.
Link tham khảo: https://gorm.io/
All rights reserved