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.