2015-11-07 60 views
4

正如标题所说,我不知道,如果有多个sql.Open语句是好事还是坏事或者是什么,或者我应该只用一个init文件是这样的:我的程序中应该多频繁地调用sql.Open?

var db *sql.DB 


func init() { 
    var err error 
    db, err = sql.Open 
} 

只是想知道什么最好的做法是。谢谢!

回答

4

您至少应该检查错误。
作为“Connecting to a database”中提到:

注意Open不直接打开一个数据库连接:这是推迟到查询时。为了验证,查询数据之前,一个连接可以,使用Ping功能:

if err := db.Ping(); err != nil { 
    log.Fatal(err) 
} 

使用后,该数据库使用关闭关闭。

如果可能,请将打开的与数据库的连接数限制到最小。
请参阅“Go/Golang sql.DB reuse in functions”:

你不应该需要所有的地方打开数据库连接。
database/sql包在内部执行连接池,根据需要打开和关闭连接,同时提供可同时使用的单个连接的错觉。

由于elithrar指出in the commentdatabase.sql/#Open确实提到:

返回的数据块是由多个够程同时使用安全和维护它自己的空闲连接池。
因此,Open函数应该只调用一次。
很少有必要关闭数据库。

由于mentioned here

声明*sql.DB全球范围内也有一些额外的好处,如SetMaxIdleConns(调节连接池的大小),或在您的应用程序preparing SQL语句。

可以使用function init,这将运行,即使您没有main()

var db *sql.DB 
func init() { 
    db, err = sql.Open(DBparms....) 
} 

init()总是被调用,而不管是否有主或没有,所以如果你进口一个具有init函数的包,它将被执行。
每个包可以有多个init()函数,它们将按照它们在代码中显示的顺序执行(当然,所有变量都被初始化)。

+0

你会说我在原始文章中描述的方式是一种体面的方式吗?为我的包设置一个数据库全局变量,然后用'init'然后'ping'来设置它?我会在哪里放置'延期关闭'?您的答案非常棒,能够回答大多数问题,但另一个问题是打开初始连接的最佳方式。就像我没有'main()'函数一样。谢谢! – Datsik

+0

@Datsik - 一个全局池(无论是作为全局变量还是使用明确传递的指针)都很好 - 请参阅https://golang.org/pkg/database/sql/#Open - '因此,Open函数应该只被称为一次。' – elithrar

+0

嘿谢谢你的梦幻般的答案。如果只有一个init文件是不好的做法,因为它在我的包中有两个文件,没有main,因为我不需要添加第三个文件并将其称为'init.go'声明我的数据库? – Datsik

相关问题