0

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

Screenshot 2025-05-26 at 08.29.51.png

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

Screenshot 2025-05-26 at 09.09.32.png

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

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí