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 giữa database và các Go struct, xây dựng câu truy vấn bằng API Go, thực hiện CRUD, quản lý quan hệ giữa các model và xử lý transaction.
Ví dụ, thay vì viết SQL thủ công:
SELECT id, name, email
FROM users
WHERE active = true
ORDER BY created_at DESC;
Có thể dùng Bun:
var users []User
err := db.NewSelect().
Model(&users).
Where("active = ?", true).
OrderExpr("created_at DESC").
Scan(ctx)
Bun xây dựng và thực thi truy vấn, sau đó ánh xạ kết quả vào slice users.
2. Bun hoạt động như thế nào?
Bun có thể được nhìn nhận qua ba thành phần chính:
- Model: Go struct đại diện cho dữ liệu trong database.
- Query builder: API Go dùng để xây dựng câu lệnh SQL.
- Database execution: thực thi SQL thông qua driver và ánh xạ kết quả trở lại Go struct.
Luồng xử lý thường diễn ra như sau:
- Developer định nghĩa model bằng Go struct.
- Bun sử dụng metadata và các tag để xác định bảng, cột và quan hệ.
- Query builder xây dựng câu SQL từ các điều kiện đã khai báo.
- Database driver gửi truy vấn đến database.
- Bun nhận kết quả và ánh xạ các cột vào struct.
3. Khai báo Model và ánh xạ bảng
Model là nền tảng để Bun biết cách ánh xạ giữa struct Go và bảng database.
Ví dụ:
type User struct {
bun.BaseModel `bun:"table:users,alias:u"`
ID int64 `bun:"id,pk,autoincrement"`
Name string `bun:"name,notnull"`
Email string `bun:"email,notnull"`
IsActive bool `bun:"is_active,notnull,default:true"`
CreatedAt time.Time `bun:"created_at,nullzero,notnull,default:current_timestamp"`
}
Các thành phần quan trọng:
table:users: xác định bảngusers.alias:u: khai báo aliasuđể dùng trong truy vấn.pk: đánh dấu khóa chính.autoincrement: khai báo cột tự tăng theo cấu hình database.notnull: mô tả cột không được nhậnNULL.default:...: mô tả giá trị mặc định.nullzero: điều khiển cách Bun xử lý giá trị zero trong một số thao tác mapping và ghi dữ liệu.
bun.BaseModel cung cấp metadata về bảng và alias. Với model có nhu cầu phức tạp hơn, có thể sử dụng tag bổ sung hoặc cấu hình quan hệ tương ứng.
4. Quan hệ giữa các Model
Belongs To
Ví dụ mỗi bài viết thuộc về một người dùng.
type User struct {
bun.BaseModel `bun:"table:users,alias:u"`
ID int64 `bun:"id,pk,autoincrement"`
Name string `bun:"name,notnull"`
}
type Post struct {
bun.BaseModel `bun:"table:posts,alias:p"`
ID int64 `bun:"id,pk,autoincrement"`
UserID int64 `bun:"user_id,notnull"`
Title string `bun:"title,notnull"`
Author *User `bun:"rel:belongs-to,join:user_id=id"`
}
Quan hệ này mô tả posts.user_id tham chiếu đến users.id. Database vẫn nên có foreign key nếu nghiệp vụ cần bảo vệ tính toàn vẹn tham chiếu.
Has Many
Một người dùng có nhiều bài viết:
type User struct {
bun.BaseModel `bun:"table:users,alias:u"`
ID int64 `bun:"id,pk,autoincrement"`
Name string `bun:"name,notnull"`
Posts []Post `bun:"rel:has-many,join:id=user_id"`
}
5. Transaction – Quản lý giao dịch
Transaction giúp nhóm nhiều thao tác database thành một đơn vị nghiệp vụ.
Ví dụ, tạo đơn hàng và các dòng sản phẩm cần được thực hiện nhất quán. Nếu một thao tác thất bại, các thay đổi trước đó nên được rollback.
err := db.RunInTx(ctx, nil, func(
ctx context.Context,
tx bun.Tx,
) error {
order := &Order{
UserID: 1,
Status: "PENDING",
}
if _, err := tx.NewInsert().
Model(order).
Exec(ctx); err != nil {
return err
}
item := &OrderItem{
OrderID: order.ID,
ProductID: 10,
Quantity: 2,
}
if _, err := tx.NewInsert().
Model(item).
Exec(ctx); err != nil {
return err
}
return nil
})
if err != nil {
return err
}
Đây là ví dụ minh họa. Các model Order và OrderItem cần được khai báo tương ứng với schema thật; nếu ID được sinh từ database, cần bảo đảm nó đã được đọc về trước khi sử dụng. Khi callback trả về lỗi, transaction được rollback; khi callback thành công, Bun hoàn tất transaction theo cơ chế của thư viện.
6. Tổng kết
Bun là thư viện ORM và SQL query builder cho Go, giúp làm việc với database quan hệ thông qua Go struct và API truy vấn.








Khoá học lập trình game con rắn cho trẻ em




