SQLX 在以下接口中实现了非常有趣的抽象:
这些接口在整个库中被用作以字符串形式表示 SQL 查询功能的接口。
例如:
db, err := sqlx.Connect("postgres", "user=foo dbname=bar sslmode=disable")
if err != nil {
log.Fatalln(err)
}
db.MustExec("CREATE TABLE person (first_name text)")
实际上,最后一行等同于:
sqlx.MustExec(db, "CREATE TABLE person (first_name text)")
在使用 db
作为 Execer
的情况下:
同样地,这个例子也是如此:
people := []Person{}
db.Select(&people, "SELECT * FROM person ORDER BY first_name ASC")
相当于:
sqlx.Select(db, &people, "SELECT * FROM person ORDER BY first_name ASC")
在这里,db
被用作 Queryer
。
如果你不想直接使用 DB
类型,而是使用库中底层的自由函数,你可以使用以下结构将你的 db
包装成执行日志记录的对象:
type QueryLogger struct {
queryer sqlx.Queryer
logger *log.Logger
}
func (p *QueryLogger) Query(query string, args ...interface{}) (*sql.Rows, error) {
p.logger.Print(query, args...)
return p.queryer.Query(query, args...)
}
func (p *QueryLogger) Queryx(query string, args ...interface{}) (*Rows, error) {
p.logger.Print(query, args...)
return p.queryer.Queryx(query, args...)
}
func (p *QueryLogger) QueryRowx(query string, args ...interface{}) *Row {
p.logger.Print(query, args...)
return p.queryer.QueryRowx(query, args...)
}
当连接到您的数据库时:
db, err := sqlx.Connect("postgres", "user=foo dbname=bar sslmode=disable")
if err != nil {
log.Fatalln(err)
}
ql := &QueryLogger{db, yourLogger}
sqlx.Select(ql, &people, "SELECT * FROM person ORDER BY first_name ASC")
当然,这只适用于使用sqlx库的免费函数时。如果你的代码有大量调用sqlx.DB类型的函数,则这可能不太方便。