2015-07-03 68 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會話的每個函數中都有一行,這是一個簡單的函數調用。如果你總是需要一個新的數據庫會話,你不可能縮短它。