我是golang的新手。我试图在我的包中共享mysql数据库连接,后者可能在几个包中。要跳过在每个包中定义数据库连接,我已经创建了数据库包,现在我试图获取该包,连接到db并在整个包中使用该对象。
我正在使用这个mysql插件:github.com/go-sql-driver/mysql
这是我的代码:
main.go
package main
import (
"log"
"./packages/db" // this is my custom database package
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
var dbType Database.DatabaseType
var db *sql.DB
func main() {
log.Printf("-- entering main...")
dbType := Database.New()
db = dbType.GetDb()
dbType.DbConnect()
delete_test_data()
dbType.DbClose()
}
func delete_test_data(){
log.Printf("-- entering delete_test_data...")
//db.Exec("DELETE FROM test;")
}
包/分贝/ db.go
package Database
import (
"log"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
type DatabaseType struct {
DatabaseObject *sql.DB
}
func New()(d *DatabaseType) {
d = new(DatabaseType)
//db.DatabaseObject = db.DbConnect()
return d
}
func (d *DatabaseType) DbConnect() *DatabaseType{
log.Printf("-- entering DbConnect...")
var err error
if d.DatabaseObject == nil {
log.Printf("--------- > Database IS NIL...")
d.DatabaseObject, err = sql.Open("mysql", "...")
if err != nil {
panic(err.Error())
}
err = d.DatabaseObject.Ping()
if err != nil {
panic(err.Error())
}
}
return d
}
func (d *DatabaseType) DbClose(){
log.Printf("-- entering DbClose...")
defer d.DatabaseObject.Close()
}
func (d *DatabaseType) GetDb() *sql.DB{
return d.DatabaseObject
}
一切正常,没有错误,直到我取消注释这一行:
db.Exec("DELETE FROM test;")
有人能告诉我共享数据库连接的正确方法吗?
答案 0 :(得分:1)
您的dbType.DbConnect()
方法返回带有初始化连接的DatabaseType
,但您完全忽略了返回值。
此外 - 为了简化代码 - 请考虑使用New(host string) *DB
而不是三个不同的函数(New / DbConnect / GetDb)执行相同的操作。
e.g。
package datastore
type DB struct {
// Directly embed this
*sql.DB
}
func NewDB(host string) (*DB, error) {
db, err := sql.Open(...)
if err != nil {
return nil, err
}
return &DB{db}, nil
}
package main
var db *datastore.DB
func main() {
var err error
db, err = datastore.NewDB(host)
if err != nil {
log.Fatal(err)
}
err := someFunc()
}
func someFunc() error {
rows, err := db.Exec("DELETE FROM ...")
// Handle the error, parse the result, etc.
}
这减少了您必须执行的操作,您仍然可以在数据库类型上调用close,因为它嵌入了*sql.DB
- 不需要实现自己的Close()
方法。