[Golang] Chiến Lược Quản Lý Kết Nối Database Thông Qua Gorm
Nói đến Gorm chắc đa số các bạn develop Golang điều biết, nhưng hôm nay mình giới thiệu cách để quản lý kết nối đến database ( không đề cập đến connection pool)
Có 2 cách để connect đến Gorm:
Cách 1
- đoạn mã code.
type (
dbInstance struct {
db *gorm.DB
}
)
func NewDBInstanceRepository(db *gorm.DB) *dbInstance {
return &dbInstance{
db: db,
}
}
func (l *dbInstance) getDB() *gorm.DB {
return l.db
}
- Giải thích:
- Định nghĩa dbInstance,
dbInstance
là một struct có một trườngdb
kiểu*gorm.DB
, biểu thị một kết nối đến cơ sở dữ liệu.
- Hàm NewDBInstanceRepository:
- Hàm này là một constructor để khởi tạo một instance của
dbInstance
. - Nó nhận một tham số
*gorm.DB
(kết nối cơ sở dữ liệu) và trả về một con trỏ củadbInstance
.
- Hàm này là một constructor để khởi tạo một instance của
- Hàm getDB:
- Đây là một getter để truy xuất đối tượng
*gorm.DB
từdbInstance
.
- Đây là một getter để truy xuất đối tượng
- Công dụng:
- Đoạn mã này giúp đóng gói kết nối cơ sở dữ liệu
(*gorm.DB)
vào một struct, đồng thời cung cấp phương pháp truy cập qua hàmgetDB
. Đây là cách tiếp cận đơn giản và thường dùng khi bạn muốn quản lý kết nối cơ sở dữ liệu trong một phạm vi hẹp.
Cách 2
- Code:
var dbs sync.Map
type DB struct {
*gorm.DB
}
type DBConf struct {
Driver string `yaml:"Driver"`
Host string `yaml:"Host"`
Port int64 `yaml:"Port"`
User string `yaml:"User"`
Password string `yaml:"Password"`
Db string `yaml:"Db"`
Schema string `yaml:"Schema"`
}
// DbGet get db connection for specified conf
func DbGet(conf DBConf, ops ...func(*gorm.DB)) *DB {
dsn := "config url"
db, ok := dbs.Load(dsn)
if !ok {
logger.Infof("connecting '%s' '%s' '%s' '%d' '%s'", conf.Driver, conf.Host, conf.User, conf.Port, conf.Db)
db1, err := gorm.Open(getGormDialetor(conf.Driver, dsn), &gorm.Config{
})
dtmimp.E2P(err)
err = db1.Use(&tracePlugin{})
dtmimp.E2P(err)
db = &DB{DB: db1}
for _, op := range ops {
op(db1)
}
dbs.Store(dsn, db)
}
return db.(*DB)
}
- Giải thích:
- Sử dụng sync.Map:
sync.Map
là một cấu trúc dữ liệu thread-safe cho việc lưu trữ các kết nối cơ sở dữ liệu (DB) theo khóadsn
(Data Source Name).- Điều này đảm bảo việc truy cập/kết nối là an toàn khi có nhiều goroutines.
- Struct
DB
:DB
là một wrapper cho*gorm.DB
.
- Hàm
DbGet
:- Nhận cấu hình cơ sở dữ liệu conf kiểu
DBConf
và một số thao tác bổ sung (quaops
). - Tạo dsn từ cấu hình thông qua dtmimp.GetDsn.
- Kiểm tra xem kết nối với dsn đã tồn tại trong sync.Map chưa.
- Nếu chưa, nó sẽ:
- Kết nối cơ sở dữ liệu qua
gorm.Open
. - Lưu kết nối này vào
sync.Map
.
- Nếu đã tồn tại, lấy kết nối ra và trả về.
- Nhận cấu hình cơ sở dữ liệu conf kiểu
- Công dụng:
- Đảm bảo mỗi
dsn
chỉ có một kết nối duy nhất (Singleton pattern). - Hỗ trợ thread-safe khi sử dụng trong các ứng dụng đa luồng hoặc microservices.
- Tiện lợi khi cần sử dụng nhiều kết nối cơ sở dữ liệu với các cấu hình khác nhau.
So sánh và ứng dụng:
Đặc điểm | Code 1 | Code 2 |
---|---|---|
Mục tiêu | Quản lý đơn giản một kết nối cơ sở dữ liệu. | Quản lý nhiều kết nối cơ sở dữ liệu. |
Phạm vi sử dụng | Ứng dụng nhỏ, ít kết nối. | Ứng dụng lớn, nhiều kết nối, đa luồng. |
Quản lý kết nối | Không có quản lý đồng bộ (thread-safe). | Đồng bộ qua sync.Map. |
Phức tạp | Đơn giản, dễ hiểu. | Phức tạp hơn do xử lý nhiều kết nối |
- Tùy vào nhu cầu, bạn chọn cách tiếp cận phù hợp. Code 1 thích hợp cho ứng dụng nhỏ gọn, trong khi Code 2 tối ưu cho các hệ thống phức tạp và yêu cầu đồng bộ cao.
All Rights Reserved