1 回答
TA贡献1809条经验 获得超8个赞
sqlx 具有以下接口形式的非常有趣的抽象:
sqlx.Execer
sqlx.Queryer
它们在整个库中都用作接口,表示使用字符串作为 SQL 查询的功能。
例如:
db, err := sqlx.Connect("postgres", "user=foo dbname=bar sslmode=disable")
if err != nil {
log.Fatalln(err)
}
// exec the schema or fail; multi-statement Exec behavior varies between
// database drivers; pq will exec them all, sqlite3 won't, ymmv
db.MustExec("CREATE TABLE person (first_name text)")
最后一行实际上相当于:
sqlx.MustExec(db, "CREATE TABLE person (first_name text)")
wheredb用作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")
wheredb用作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类型的调用,这可能不够方便。
- 1 回答
- 0 关注
- 163 浏览
添加回答
举报