1. GORM là gì?

GORM (Go ORM) là thư viện Object-Relational Mapping dành cho Go, giúp làm việc với cơ sở dữ liệu quan hệ thông qua các struct và API của Go thay vì phải viết SQL cho mọi thao tác.

Trong một ứng dụng backend, dữ liệu thường được lưu trong PostgreSQL, MySQL hoặc SQLite. Nếu không sử dụng ORM, developer thường phải tự viết câu SQL, truyền tham số, thực thi truy vấn và chuyển kết quả từ các hàng trong database thành struct Go.

Ví dụ, thay vì viết SQL:

SELECT * FROM users WHERE id = 1;

Có thể dùng GORM:

var user User

result := db.First(&user, 1)
if result.Error != nil {
    return result.Error
}

GORM sẽ xây dựng và thực thi truy vấn phù hợp với database driver đang sử dụng, sau đó ánh xạ dữ liệu trả về vào biến user.

2. ORM hoạt động như thế nào?

Để sử dụng GORM hiệu quả, cần hiểu vai trò của từng thành phần.

Giả sử ứng dụng quản lý người dùng. Trong Go, ta định nghĩa:

type User struct {
    ID    uint
    Name  string
    Email string
}

Struct User biểu diễn dữ liệu trong chương trình. GORM dựa trên cấu trúc này và các quy ước mặc định để ánh xạ sang bảng trong database.

Một thao tác như:

user := User{
    Name:  "An",
    Email: "[email protected]",
}

result := db.Create(&user)

sẽ đi qua các bước khái quát:

  1. GORM đọc cấu trúc model và thông tin cấu hình.
  2. GORM xây dựng câu SQL tương ứng.
  3. Database driver gửi truy vấn đến database.
  4. Database thực thi câu SQL và trả về kết quả.
  5. GORM cập nhật các thông tin liên quan vào struct, chẳng hạn ID được sinh tự động.
  6. Ứng dụng kiểm tra lỗi qua result.Error.

3. Model trong GORM

Model là thành phần cốt lõi của GORM. Một model thường biểu diễn một thực thể nghiệp vụ và được ánh xạ tới một bảng trong database.

Định nghĩa model

type User struct {
    ID    uint
    Name  string
    Email string
    Age   int
}

Theo quy ước mặc định, GORM thường ánh xạ model này tới bảng users.

Sử dụng gorm.Model

GORM cung cấp struct nền gorm.Model:

type User struct {
    gorm.Model

    Name  string
    Email string
}

gorm.Model bao gồm các trường:

type Model struct {
    ID        uint
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt gorm.DeletedAt
}

Tùy chỉnh tên bảng

Có thể ghi đè quy ước tên bảng bằng phương thức TableName:

type User struct {
    ID   uint
    Name string
}

func (User) TableName() string {
    return "app_users"
}

Khi đó, model User được ánh xạ tới bảng app_users.

4. Associations – Quan hệ giữa các model

Trong database quan hệ, các bảng thường liên kết với nhau bằng foreign key. GORM hỗ trợ ánh xạ những mối quan hệ này thành các field trong struct.

Ba nhóm quan hệ cơ bản là:

  • One-to-One: một-một.
  • One-to-Many / Many-to-One: một-nhiều / nhiều-một.
  • Many-to-Many: nhiều-nhiều.

Belongs To – Quan hệ nhiều-một

Ví dụ nhiều bài viết thuộc về một người dùng:

type User struct {
    ID   uint
    Name string
}

type Post struct {
    ID     uint
    Title  string
    UserID uint
    User   User
}

Post.UserID là foreign key tham chiếu đến người dùng. Post.User biểu diễn quan hệ trong model.

Truy vấn bài viết cùng thông tin người dùng:

var post Post

err := db.Preload("User").
    First(&post, 1).Error

Has Many – Quan hệ một-nhiều

Một người dùng có thể có nhiều bài viết:

type User struct {
    ID    uint
    Name  string
    Posts []Post
}

type Post struct {
    ID     uint
    Title  string
    UserID uint
}

Có thể tải người dùng cùng các bài viết:

var user User

err := db.Preload("Posts").
    First(&user, 1).Error

Has One – Quan hệ một-một

Ví dụ một người dùng có một hồ sơ chi tiết:

type User struct {
    ID      uint
    Name    string
    Profile Profile
}

type Profile struct {
    ID     uint
    Bio    string
    UserID uint
}

Profile.UserID liên kết hồ sơ với người dùng.

var user User

err := db.Preload("Profile").
    First(&user, 1).Error

Nếu quan hệ là một-một theo nghiệp vụ, nên thiết lập unique constraint cho foreign key phù hợp. Khai báo struct không tự nó thay thế việc thiết kế constraint ở database.

5. Tổng kết

GORM là một ORM giúp developer Go làm việc với database quan hệ thông qua model và API Go, giảm lượng code CRUD lặp lại và hỗ trợ nhiều tính năng như association, transaction, migration, hooks, logging và query builder.

Tuy nhiên, sử dụng GORM hiệu quả không chỉ là ghi nhớ cú pháp. Developer cần hiểu SQL được sinh ra, cách database thực thi truy vấn, cơ chế transaction, các ràng buộc dữ liệu và những đánh đổi về hiệu năng.

Các nguyên tắc cần ghi nhớ:

  • Model biểu diễn cấu trúc dữ liệu; schema thực tế vẫn cần được quản lý.
  • Luôn kiểm tra lỗi sau thao tác database.
  • Hiểu cách Updates xử lý zero-value.
  • Dùng parameterized query và kiểm soát SQL động.
  • Dùng transaction khi nhiều thay đổi cần thành công hoặc thất bại cùng nhau.
  • Dùng Preload hoặc Joins đúng mục đích để tránh N+1 Query.
  • Kiểm tra SQL và execution plan khi tối ưu hiệu năng.
  • Đặt logic nghiệp vụ phức tạp ở service layer thay vì phụ thuộc hoàn toàn vào hooks.
  • Kết hợp GORM với SQL trực tiếp khi điều đó làm truy vấn rõ ràng hoặc hiệu quả hơn.

 

Bài viết khác

Positive vs Negative Testing(Kiểm thử tích cực và Kiểm thử tiêu cực)

1.Positive vs Negative Testing là gì? Trong ngành công nghệ phần mềm, chất lượng sản phẩm không bao giờ là một khái niệm đơn chiều. Một ứng dụng được lập trình hoàn hảo trên lý thuyết vẫn có thể sụp đổ hoàn toàn ngay trong ngày đầu tiên phát hành nếu nó chỉ được chuẩn […]

Bun ORM

1. Bun ORM là gì? Bun là một thư viện ORM và SQL query builder dành cho Go, được thiết kế để làm việc với các cơ sở dữ liệu quan hệ như PostgreSQL, MySQL, SQLite và một số hệ quản trị khác thông qua driver tương ứng. Bun giúp developer ánh xạ dữ liệu […]

State Transition Testing(Kiểm thử chuyển đổi trạng thái)

1.State Transition Testing là gì? Trong các hệ thống phần mềm doanh nghiệp hiện đại, phần lớn các ứng dụng không hoạt động một cách tĩnh (static) mà mang tính động (dynamic) mạnh mẽ. Trạng thái phản hồi của một hệ thống tại một thời điểm không chỉ phụ thuộc vào đầu vào hiện tại, […]

JSON Serialization / Deserialization

       JSON, viết tắt của JavaScript Object Notation, là một trong những định dạng được sử dụng phổ biến nhất hiện nay nhờ cấu trúc đơn giản, dễ đọc và được hỗ trợ bởi hầu hết các ngôn ngữ lập trình. Hai thao tác quan trọng khi làm việc với JSON là serialization […]

REST API & HTTP

        Trong quá trình phát triển của công nghệ thông tin, nhu cầu kết nối các ứng dụng, thiết bị và dịch vụ ngày càng trở nên quan trọng. Một ứng dụng hiện đại hiếm khi hoạt động hoàn toàn độc lập. Ứng dụng di động cần trao đổi dữ liệu với […]

PostgreSQL / MySQL

  1. PostgreSQL và MySQL là gì? PostgreSQL và MySQL là hai hệ quản trị cơ sở dữ liệu quan hệ (Relational Database Management System – RDBMS) được sử dụng phổ biến trong phát triển phần mềm. Cả hai đều cho phép lưu trữ, tổ chức, truy vấn và quản lý dữ liệu bằng SQL. […]

Leave a Reply

Your email address will not be published. Required fields are marked *