dsoihsnz85757 2015-10-09 14:39
浏览 149
已采纳

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

I'm using a non-framework Go stack with sqlx, and MySQL for a web project.

I would like to log all outgoing SQL statements for debugging. Is it possible to do this? Hopefully looking to get output like this (copied from a Rails project):

  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条回答 默认 最新

  • douqi2571 2015-10-09 15:26
    关注

    sqlx has a very interesting abstraction in the form of the following interfaces:

    They are used all through the library as the interfaces representing the functionality of using strings as SQL queries.

    For example:

    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)")
    

    The last line is in fact equivalent to:

    sqlx.MustExec(db, "CREATE TABLE person (first_name text)")
    

    Where db is used as an Execer.

    In the same vein, this:

    people := []Person{}
    db.Select(&people, "SELECT * FROM person ORDER BY first_name ASC")
    

    is equivalent to:

    sqlx.Select(db, &people, "SELECT * FROM person ORDER BY first_name ASC")
    

    where db is used as a Queryer.

    So if you are willing not to use the DB type directly but instead use the underlying free functions of the library, you can use the following structure to wrap your db into objects that perform logging:

    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...)
    }
    

    And when connecting to your database:

    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")
    

    Of course this only works when using the free functions of the sqlx library, so if your code has a large amount of calls using the sqlx.DB type, this will probably not be convenient enough.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!