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ấn Select.

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 LISTENNOTIFY 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ột Profile
  • Trường ProfileUserID 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ều Post
  • Trường UserID trong Post là khóa ngoại đến User

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ều Role
  • Một Role có thể gán cho nhiều User
  • Bảng user_roles là bảng trung gian

About the Author

Đức Phát

View all author's posts

Leave a Comment

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

Bài viết khác

So sánh giữa gorm vs go-pg vs bun

Trong thế giới phát triển Golang, việc tương tác với cơ sở dữ liệu là một phần không thể thiếu của hầu hết các ứng dụng. Để đơn giản hóa quy trình này, các thư viện ORM (Object-Relational Mapping) ra đời, giúp các nhà phát triển thao tác với database thông qua các đối tượng […]

So sánh GORM vs go-pg vs Bun

Cộng đồng GORM Là ORM phổ biến nhất trong cộng đồng Go. Có nhiều tài liệu, ví dụ, StackOverflow câu trả lời, và nhiều package hỗ trợ mở rộng. Nhiều developer đã từng dùng Gorm. go-pg Từng rất phổ biến khi chỉ dùng PostgreSQL, nhưng đang bị Bun thay thế dần. Ít được duy trì […]

clean architecture golang

  1.Clean Architecture là gì? Clean Architecture là một kiến trúc phần mềm được đề xuất bởi Robert C. Martin (Uncle Bob) nhằm mục tiêu tách biệt rõ ràng giữa các tầng trong ứng dụng, giúp mã nguồn dễ bảo trì, mở rộng, và kiểm thử. 2.Tổng quan kiến trúc Entity (Domain Model): Là tầng […]

Tìm hiểu Hexagonal Architecture

Hexagonal Architecture là gì? Hexagonal Architecture (tên gọi khác là ports and adapters architecture), là một mẫu kiến trúc được dùng trong thiết kế phần mềm. Nó hướng tới việc xây dựng ứng dụng xoay quanh business/application logic mà không ảnh hưởng hoặc phụ thuộc bởi bất kì thành phần bên ngoài, mà chỉ giao […]

Sử dụng Request/Response trong ứng dụng RESTful mô hình MVC

DTO là gì? DTO (Data Transfer Object) là một object trung gian dùng để truyền dữ liệu giữa client – server hoặc giữa các service trong ứng dụng web/API theo kiến trúc RESTful API. DTO chỉ chứa các thông tin cần thiết mà client hoặc service khác cần (ví dụ: Login Form chỉ cần thông […]

Docker

Docker là gì? Docker là một nền tảng mã nguồn mở cho phép bạn đóng gói, phân phối và chạy ứng dụng bên trong các “container” – những môi trường ảo nhẹ, cô lập nhưng vẫn chia sẻ nhân hệ điều hành của máy chủ. Khái niệm then chốt ở đây là “containerization”: thay vì […]