我博客的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 明明有很多完全相同的方法。
// 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
}
参考:
这篇文章的内容已被作者标记为“过时”/“需要更新”/“不具参考意义”。