go-pg là một thư viện ORM (Object-Relational Mapping) và trình điều khiển PostgreSQL cho ngôn ngữ lập trình Go. Nó cung cấp một cách tiện lợi để tương tác với cơ sở dữ liệu PostgreSQL bằng cách ánh xạ các cấu trúc (structs) trong Go thành các bảng trong cơ sở dữ liệu và ngược lại.
Ưu điểm của go-pg
- Dễ sử dụng: Cung cấp API trực quan để thực hiện các thao tác CRUD (Create, Read, Update, Delete).
- Hiệu suất cao: Được thiết kế để có hiệu suất tốt, tạo ra các truy vấn SQL hiệu quả.
- Hỗ trợ đầy đủ tính năng của PostgreSQL: Tận dụng các tính năng riêng của PostgreSQL như Array, Hstore, JSONB, LISTEN/NOTIFY, COPY, v.v.
- ORM và SQL thuần túy: Cho phép bạn làm việc với các model (structs) theo kiểu ORM hoặc viết các truy vấn SQL thuần túy khi cần kiểm soát chi tiết hơn.
Các tính năng chính của go-pg
Kết nối và Cấu hình:
- Thiết lập kết nối với PostgreSQL bằng chuỗi kết nối hoặc các tùy chọn riêng biệt.
- Hỗ trợ pool kết nối để quản lý hiệu quả các kết nối database.
Định nghĩa Model (Structs):
- Ánh xạ các trường của struct Go với các cột trong bảng PostgreSQL bằng cách sử dụng
struct tags
. - Ví dụ:
json:"id"
để ánh xạ với JSON,pg:"column_name,notnull,unique"
để cấu hình cột database. - Hỗ trợ các kiểu dữ liệu cơ bản của Go và PostgreSQL, bao gồm cả
time.Time
,net.IP
,net.IPNet
,sql.Null*
. - Tự động chuyển đổi structs, maps, và slices thành JSON khi lưu trữ vào cột JSONB.
Truy vấn (Queries):
- ORM-style queries:
db.Model(&user).Select()
: Lấy dữ liệu.db.Model(&user).Insert()
: Chèn dữ liệu mới.db.Model(&user).Where("id = ?", user.ID).Update()
: Cập nhật dữ liệu.db.Model(&user).Where("id = ?", user.ID).Delete()
: Xóa dữ liệu.- Hỗ trợ các điều kiện
Where
,Limit
,Offset
,Order
,Group
,Having
. ColumnExpr
: Cho phép bạn sử dụng các biểu thức SQL tùy chỉnh trong truy vấn.
- Raw SQL queries:
db.Query(model, "SELECT * FROM users WHERE id = ?", id)
: Thực thi truy vấn SQL thuần túy và scan kết quả vào model hoặc biến.db.Exec("UPDATE users SET name = ? WHERE id = ?", name, id)
: Thực thi các câu lệnh SQL không trả về hàng.
Quan hệ (Relations):
- Hỗ trợ các loại quan hệ phổ biến:
Has One
: Một-một.Belongs To
: Một-một (chiều ngược lại của Has One).Has Many
: Một-nhiều.Many To Many
: Nhiều-nhiều.
- Sử dụng
Relation
để load các quan hệ trong truy vấnSelect
.
Giao dịch (Transactions):
- Hỗ trợ các giao dịch cơ sở dữ liệu (
BEGIN
,COMMIT
,ROLLBACK
). - Có hàm tiện ích
db.RunInTransaction
để đơn giản hóa việc quản lý giao dịch (tự động rollback nếu có lỗi, commit nếu thành công).
Migrations (Di chuyển schema):
- Cung cấp package
github.com/go-pg/migrations
để quản lý các thay đổi schema database theo thời gian. - Hỗ trợ cả migration bằng file SQL và migration bằng code Go.
Tính năng nâng cao:
- Listeners và Notifiers: Tương tác với tính năng
LISTEN
vàNOTIFY
của PostgreSQL. - COPY: Chức năng COPY FROM/TO để nhập/xuất dữ liệu hàng loạt hiệu quả.
- Hooks: Cho phép bạn thực thi code trước hoặc sau các thao tác database (ví dụ:
BeforeInsert
,AfterSelect
). - Soft Deletes: Hỗ trợ xóa mềm (thay vì xóa hẳn record, chỉ đánh dấu nó là đã xóa).
- Circuit Breaker và Retries: Hỗ trợ tự động thử lại truy vấn khi gặp lỗi mạng và circuit breaking để ngăn ngừa việc quá tải database.
- Debugging: Có thể log các truy vấn SQL được tạo ra bởi
go-pg
để debug.
Ví dụ một số model quan hệ
Quan hệ One-to-One
type Profile struct { tableName struct{} `pg:"profiles"` ID int UserID int Bio string } type User struct { tableName struct{} `pg:"users"` ID int Name string Profile *Profile `pg:"rel:has-one"` }
- Một
User
có mộtProfile
- Trường
Profile
cóUserID
làm khóa ngoại.
Quan hệ One-to-Many
type Post struct { tableName struct{} `pg:"posts"` ID int Title string UserID int } type User struct { tableName struct{} `pg:"users"` ID int Name string Posts []*Post `pg:"rel:has-many"` }
- Một
User
có nhiềuPost
- Trường
UserID
trongPost
là khóa ngoại đếnUser
Quan hệ Many-to-Many (thông qua bảng trung gian)
type User struct { tableName struct{} `pg:"users"` ID int Name string Roles []Role `pg:"many2many:user_roles"` } type Role struct { tableName struct{} `pg:"roles"` ID int Name string } type UserRole struct { tableName struct{} `pg:"user_roles"` UserID int RoleID int }
- Một
User
có thể có nhiềuRole
- Một
Role
có thể gán cho nhiềuUser
- Bảng
user_roles
là bảng trung gian