首页 文章

与包共享数据库连接

提问于
浏览
0

我是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 / 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;")

有人能告诉我共享数据库连接的正确方法是什么?

1 回答

  • 1

    您的 dbType.DbConnect() 方法返回带有初始化连接的 DatabaseType ,但您完全忽略了返回值 .

    进一步 - 为了简化你的代码 - 看看有 New(host string) *DB 而不是三个不同的功能(New / DbConnect / GetDb)做同样的事情 .

    例如

    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.
    }
    

    这减少了你必须要做的杂耍,你仍然可以调用你的数据库类型关闭,因为它嵌入了 *sql.DB - 你不需要实现自己的 Close() 方法 .

相关问题