如何在GoLang中创建单例DB类

:如何在GoLang中创建单例DBManager类。

我参考了一些有关如何创建单例的代码示例,但是我希望在其中包含方法,并在其单例引用中对其进行调用。我的代码如下

package dbprovider

import (

"github.com/jinzhu/gorm"

_"github.com/jinzhu/gorm/dialects/sqlite"

"rest/article"

"log"

)

type DBOperations interface {

AddArticle(article *article.Article)

}

type DBManager struct {

db *gorm.DB

isInitialized bool

}

var dbManagerInstance = new()

func GetDBManager() DBManager {

return dbManagerInstance

}

func new() DBManager {

localDbRef, err := gorm.Open("sqlite3", "../articles.db")

if (err != nil) {

panic("Error initializing db")

} else {

log.Print("DB Initialized successfully")

}

return DBManager{db:localDbRef, isInitialized:true}

}

func (dbManager DBManager) AddArticle(article article.Article) (err error) {

if (dbManager.isInitialized) {

tx := dbManager.db.Begin()

//dbManager.db.NewRecord(article)

//dbManager.db.Commit()

tx.NewRecord(article)

tx.Commit()

errs := dbManager.db.GetErrors()

if (len(errs) > 0) {

err = errs[0]

} else {

log.Print("No error in this transactions")

}

}

return

}

回答:

一种方法是使用这些方法创建一个导出的接口,并使实现类型不导出。创建接口类型的全局变量,然后使用包init()函数对其进行初始化。您不需要任何同步,因为包init()功能只能安全地运行一次。

init()在您可以从包中引用任何内容之前,包功能会在运行时自动执行一次。有关详细信息,请参见Spec:包初始化。

例如:

package dbprovider

type Manager interface {

AddArticle(article *article.Article) error

// Add other methods

}

type manager struct {

db *gorm.DB

}

var Mgr Manager

func init() {

db, err := gorm.Open("sqlite3", "../articles.db")

if err != nil {

log.Fatal("Failed to init db:", err)

}

Mgr = &manager{db: db}

}

func (mgr *manager) AddArticle(article *article.Article) (err error) {

mgr.db.Create(article)

if errs := mgr.db.GetErrors(); len(errs) > 0 {

err = errs[0]

}

return

}

使用它:

import "dbprovider"

if err := dbprovider.Mgr.AddArticle(someArticle); err != nil {

// Handle error

}

您也可以不使用任何init()功能,例如:

var Mgr = newManager()

func newManager() Manager {

db, err := gorm.Open("sqlite3", "../articles.db")

if err != nil {

log.Fatal("Failed to init db:", err)

}

return &manager{db: db}

}

这样,您可以决定进行newManager()导出,包的用户可以决定使用共享Mgr实例,或者他们可以创建另一个实例Manager(例如出于测试目的)。

Mgr是一个导出的全局变量,可以通过其他包(例如dbprovider.Mgr =

nil)为其分配新值。如果要避免这种情况,则必须使其不导出,并为其提供“获取”功能,例如:

var mgr = newManager()

func Mgr() Manager { return mgr }

并使用它:

err := dbprovider.Mgr().AddArticle(someArticle)

以上是 如何在GoLang中创建单例DB类 的全部内容, 来源链接: utcz.com/qa/420050.html

回到顶部