使用Go语言存储数据库连接的最佳做法是什么?
在Java中,您可以使用单例,一些像Spring这样的IoC容器。 它生命周期中的最佳实践是什么? 申请结束后如何发布?
答案 0 :(得分:8)
在这里使用Singleton模式也没有错。
我会用这样的东西:
var db *sql.DB = nil
func GetDB() (*sql.DB, error) {
if db == nil {
conn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=require",
DB_HOST, DB_USER, DB_PASSWORD, DB_NAME)
log.Println("Creating a new connection: %v", conn)
d, err := sql.Open("postgres", conn)
if err != nil {
return nil, err
}
db = d
}
return db, nil
}
使用此导出功能,您可以从所有其他包接收连接。
根据评论更新答案(感谢@all获取信息)!:
返回的数据库对于多个goroutine和并发使用是安全的 维护自己的空闲连接池。因此,Open功能 应该只召唤一次。很少需要关闭数据库。¹
关闭数据库很少见,因为数据库句柄是长寿命的 许多goroutines之间共享。²
我想说没有强制理由在数据库连接上调用close。我没有发现任何其他陈述。尽管如此,我还是会在defer GetDB().close()
函数中使用main
- 只是为了代码的完整性。
我想要注意的另一件事是连接应该由db.Ping()
验证,否则可以建立连接但数据库可能不存在。
使用这些新信息,我不会使用某些互斥锁来确保数据库已建立。我将创建一个新的DBInit()
并在主包的init()
函数内运行它。