您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

如何在GoLang中创建单例DB类

如何在GoLang中创建单例DB类

一种方法是使用这些方法创建一个导出的接口,并使实现类型不导出。创建接口类型的全局变量,然后使用包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)
Go 2022/1/1 18:16:32 有623人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶