为了账号安全,请及时绑定邮箱和手机立即绑定

如何从 Go/MySQL 记录所有传出的 SQL 语句?

如何从 Go/MySQL 记录所有传出的 SQL 语句?

Go
犯罪嫌疑人X 2021-11-15 15:46:18
我正在将非框架 Go 堆栈与sqlx和MySQL用于 Web 项目。我想记录所有传出的 SQL 语句以进行调试。是否有可能做到这一点?希望得到这样的输出(从 Rails 项目复制):  User Load (94.4ms)  SELECT `users`.* FROM `users` WHERE `users`.`login` = 'bondnewyork' LIMIT 1  User Load (16.3ms)  SELECT `users`.* FROM `users` WHERE `users`.`login` = 'mkovarik' LIMIT 1  User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE `users`.`login` = 'mkovarik' LIMIT 1  User Load (0.3ms)  SELECT `users`.* FROM `users` ORDER BY `users`.`id` DESC LIMIT 1  User Load (0.4ms)  SELECT `users`.* FROM `users` ORDER BY `users`.`id` DESC LIMIT 1
查看完整描述

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类型的调用,这可能不够方便。


查看完整回答
反对 回复 2021-11-15
  • 1 回答
  • 0 关注
  • 163 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信