现在你已经加载了驱动程序包,你已经准备好创建一个数据库对象了sql.DB
。
创建一个sql.DB
,你使用sql.Open()
。将返回一个*sql.DB
:
func main() { db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/test") if err != nil { log.Fatal(err) } defer db.Close() }
在所示的例子中,我们要说明几件事情:
database/sql
通常与包名称相同以避免混淆。例如,它mysql
适用于github.com/go-sql-driver/mysql。有些司机不按约定和使用的数据库名称,例如sqlite3
对于github.com/mattn/go-sqlite3和postgres
对github.com/lib/pq。database/sql
操作返回的错误。有一些特殊情况我们稍后会讨论,这样做没有意义。defer db.Close()
如果不sql.DB
应该有一个超出功能范围的生命周期,这是惯用的。sql.Open()
不建立到数据库的任何连接,也不验证驱动程序连接参数。相反,它只是准备数据库抽象以备后用。与底层数据存储的第一次实际连接将在第一次需要时被懒散地建立。如果您想立即检查数据库是否可用并可访问(例如,检查您是否可以建立网络连接并登录),请使用此操作db.Ping()并记住检查错误:
err = db.Ping() if err != nil { // 在这儿做点什么 }
尽管Close()
数据库在完成时对数据库来说很习惯,但 该sql.DB
对象的设计寿命很长。不要频繁的Open()
和Close()
数据库。相反,需要为每个需要访问的不同数据存储创建一个 sql.DB
对象,并保留该对象,直到程序完成访问该数据存储。根据需要传递它,或者以全局方式提供,但保持打开。也不要Open()
和Close()
从短暂的功能。相反,将sql.DB
这个短暂的函数作为参数传递给它。
如果您不把它sql.DB
看作是一个长期存在的对象,那么您可能会遇到问题,例如重用性差和连接共享不足,用尽可用网络资源或由于大量TCP连接处于TIME_WAIT
状态而导致零星故障。这些问题是您没有按照database/sql设计使用的迹象 。
现在是时候使用你的sql.DB
对象。