【Go】为 *sql.DB 和 *sql.Tx 提取公共的查询接口

我博客的API接口部分有一个函数一开始是这样定义的:

func (o *OptionManager) Get(db *sql.DB, name string) (string, error)

后面发现这样定义不靠谱, 因为我很有可能需要在事务中调用这个函数。也就是说,还应该这样:

func (o *OptionManager) Get(tx *sql.Tx, name string) (string, error)

但是,同样的实现明显不能实现两遍。

考虑到 Get 方法只会调用 Tx/DB 的查询接口,所以我从 Tx/DB 中抽出了公共的查询接口:

type Querier interface {
    Exec(query string, args ...interface{}) (sql.Result, error)
    Query(query string, args ...interface{}) (*sql.Rows, error)
    QueryRow(query string, args ...interface{}) *sql.Row
}

于是,我的接口方法现在改成这样了:

func (o *OptionManager) Get(db Querier, name string) (string, error)

这样的接口既支持传入*sql.DB,也支持传入*sql.Tx,可以说很优雅了。

其实我非常好奇,为什么官方没有抽象出这样的公共接口?sql.DB 和 sql.Tx 明明有很多完全相同的方法。

另外,GORM 中也有类似的实现(代码地址):

// SQLCommon is the minimal database connection functionality gorm requires.  Implemented by *sql.DB.
type SQLCommon interface {
    Exec(query string, args ...interface{}) (sql.Result, error)
    Prepare(query string) (*sql.Stmt, error)
    Query(query string, args ...interface{}) (*sql.Rows, error)
    QueryRow(query string, args ...interface{}) *sql.Row
}

参考:

发表于:2018年7月31日,阅读量:40,标签:Go · 数据库

版权声明:若非特别注明,本站所有文章均为作者原创,转载请务必注明原文地址。