2015-07-03 32 views
1

我有一个包含以下代码的数据库包。如何使数据库代码干涸

package database 

import (
    "log" 

    "github.com/jinzhu/gorm" 
    // required by gorm 
    _ "github.com/mattn/go-sqlite3" 
) 

type Podcast struct { 
    ID  int `sql:"index"` 
    Title string 
    RssURL string `sql:"unique_index"` 
    Paused bool 
    Episodes []Episode 
} 

type Episode struct { 
    ID   int `sql:"index"` 
    PodcastID int 
    Title  string 
    EnclosureURL string `sql:"unique_index"` 
    Downloaded bool 
    GUID   string `sql:"unique_index"` 
    PubDate  string 
} 

func DBSession() (db gorm.DB) { 
    sqliteSession, err := gorm.Open("sqlite3", cache.db) 
    if err != nil { 
     log.Fatal(err) 
    } 

    return sqliteSession 
} 

接下来是一堆方法,它们都以下面的代码开始。

FindSomethingByID(id int) { 
    db := DBSession() 
    db.LogMode(false) 

    // code 
} 

FindSomethingElse { 
    db := DBSession() 
    db.LogMode(false) 

    // code 
} 

调用DBSession并在每个func中设置LogMode看起来很糟糕。我只是不知道如何做得更好。有人可以帮忙吗?

回答

5

在每个函数内调用gorm.Open效率不高:Open打开一个新的连接池,应该只调用一次(see the database/sql docs,哪个gorm包装)。

一个简单的改进就是建立一个全局的gorm.DB,将它初始化为它的所有函数的init() - 例如

package database 

var db gorm.DB 

func init() { 
    var err error 
    // Note we use an = and not a := as our variables 
    // are already initialised 
    db, err = gorm.Open("sqlite3", "cache.db") 
    if err != nil { 
     log.Fatal(err) 
    } 

    // Turn off logging globally 
    db.LogMode(false) 
} 

FindSomethingByID(id int) { 
    err := db.Query("...") 
    // code 
} 

这是一个快速获胜并减少重复。

在一个更大的应用程序中,通过将它们包装在类型中并创建自定义处理程序,可以更明确地传递依赖关系(如数据库池,配置参数等)。

您也可以初始化你package main连接,并通过func New(db *gorm.DB)功能,设置一个私人的,包级变量传递的*gorm.DBdatabase包。

+0

我重新安排了我的代码,就像你上面提到的,但我现在得到一个错误src/database/database.go:48:不能分配gorm.DB db(类型* gorm.DB)在多个任务 – gregf

+0

我'我做了一个编辑。 'gorm'返回一个值而不是一个指针,与大多数其他包装数据库/ sql的包不同。 – elithrar

+0

第48行是db,err = gorm.Open(“sqlite3”,“cache.db”) – gregf

0

最明显的简化,将移动db.LogMode(false)呼叫到DBSession()功能,并给DBSession()较短的名称,如DB()

func DB() (db gorm.DB) { 
    sqliteSession, err := gorm.Open("sqlite3", cache.db) 
    if err != nil { 
     log.Fatal(err) 
    } 

    sqliteSession.LogMode(false) 
    return sqliteSession 
} 

,并用它:

FindSomethingByID(id int) { 
    db := DB() 
    // code 
} 

现在有只使用db会话的每个函数中都有一行,这是一个简单的函数调用。如果你总是需要一个新的数据库会话,你不可能缩短它。