如何清空数据库代码

huangapple go评论87阅读模式
英文:

How to dry up database code

问题

我有一个包含以下代码的数据库包。

package database

import (
	"log"

	"github.com/jinzhu/gorm"
	// 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)
   
    // 代码
}

FindSomethingElse {
	db := DBSession()
	db.LogMode(false)
   
    // 代码
}

在每个函数中调用DBSession并设置LogMode似乎不太好。我只是不知道如何更好地处理。有人可以帮忙吗?

英文:

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?

答案1

得分: 6

在每个函数中调用gorm.Open并不是很高效:Open会打开一个新的连接池,应该只调用一次(参见golang.org/pkg/database/sql/#Open中的数据库/sql文档,gorm对其进行了封装)。

一个简单的改进方法是建立一个全局的gorm.DB,在init()函数中进行初始化,并从所有的函数中使用它,例如:

package database

var db gorm.DB

func init() {
    var err error
    // 注意我们使用的是=而不是:=,因为变量已经初始化过了
    db, err = gorm.Open("sqlite3", "cache.db")
    if err != nil {
        log.Fatal(err)
    }

    // 全局关闭日志记录
    db.LogMode(false)
}

func FindSomethingByID(id int) {
    err := db.Query("...")
    // 代码
}

这是一个快速的改进,减少了重复代码。

在一个较大的应用程序中,通常更合理的做法是通过将依赖项(如DB连接池、配置参数等)封装在类型中,并创建自定义处理程序来更明确地传递它们。

你也可以在package main中初始化连接,并通过一个func New(db *gorm.DB)函数将*gorm.DB传递给database包,该函数设置一个私有的、包级别的变量。

英文:

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.

答案2

得分: 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()
    // 代码
}

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

英文:

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.

huangapple
  • 本文由 发表于 2015年7月4日 04:24:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/31213791.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定