如何清除数据库代码

I have a database package that contains the following code.

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
}

Followed by a bunch of methods that all start with the following code.

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

    // code
}

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

    // code
}

Calling DBSession and setting LogMode in each func seems bad. I just don't know how to do it better. Could someone help?

Calling gorm.Open inside every function isn't very efficient: Open opens a new connection pool, and should be called just once (see the database/sql docs, which gorm wraps).

A simple improvement is to establish a global gorm.DB, initialise it in init() it from all of your functions - e.g.

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
}

This is a quick win and reduces the repetition.

In a larger application it typically makes sense to pass dependencies (like DB pools, config params, etc.) more explicitly by wrapping them in types and creating custom handlers.

You also might initialise the connection in your package main and pass the *gorm.DB to your database package via a func New(db *gorm.DB) function that sets a private, package-level variable.

The most obvious simplification would be to move the db.LogMode(false) call into the DBSession() function, and give DBSession() a shorter name like DB():

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

    sqliteSession.LogMode(false)
    return sqliteSession
}

And using it:

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

Now there's only 1 line in each of your functions using the db session, one simple function call. You can't really make it any shorter if you always need a new db session.