dsdqpdjpq16640651 2015-10-03 12:29
浏览 27
已采纳

与软件包共享数据库连接

I'm new with golang. I'm trying to share mysql database connection in my package, latter maybe in several packages. To skip defining database connection in every package I've created Database package and now I'm trying to get that package, connect to db and use that object in whole package.

I'm using this mysql plugin: github.com/go-sql-driver/mysql

here is my code:

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;")
}

packages/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
}

Everything is ok and without error until I uncomment this line:

db.Exec("DELETE FROM test;")

Can someone tell me what is correct way to share db connection?

  • 写回答

1条回答 默认 最新

  • duanji4449 2015-10-03 13:18
    关注

    Your dbType.DbConnect() method returns a DatabaseType with an initialized connection, but you're ignoring the return value entirely.

    Further - to simplify your code - look at having New(host string) *DB instead of three different functions (New/DbConnect/GetDb) that do the same thing.

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

    This reduces the juggling you have to do, and you can still call close on your DB type because it embeds *sql.DB - there's no need to implement your own Close() method.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应
  • ¥15 matlab基于pde算法图像修复,为什么只能对示例图像有效
  • ¥100 连续两帧图像高速减法
  • ¥15 组策略中的计算机配置策略无法下发
  • ¥15 如何绘制动力学系统的相图
  • ¥15 对接wps接口实现获取元数据
  • ¥20 给自己本科IT专业毕业的妹m找个实习工作
  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?
  • ¥30 我的代码按理说完成了模型的搭建、训练、验证测试等工作(标签-网络|关键词-变化检测)