Go语言 如何将查询记录到数据库驱动程序?

2lpgd968  于 2023-03-10  发布在  Go
关注(0)|答案(2)|浏览(92)

我试图写一个简单的数据库应用程序在去访问多个数据服务器,一些MySQL,MSSQL和SqlLite 3。我正在使用“数据库/SQL”包来访问他们。

db, err := sql.Open(driver, dataSourceName)
result, err := db.Exec(
    "INSERT INTO users (name, age) VALUES (?, ?)",
    "gopher",
    27,
)

我需要将SQL查询记录到各个服务器上,以便进行调试和审计。我如何才能实现这一点?

jgwigjjp

jgwigjjp1#

假设您不想使用服务器的日志记录功能,那么显而易见的解决方案就是简单地记录所有查询。

db, err := sql.Open(driver, dataSourceName)
log.Println(dataSourceName, "INSERT INTO users (name, age) VALUES (?, ?)", "gopher", 27)
result, err := db.Exec(
    "INSERT INTO users (name, age) VALUES (?, ?)",
    "gopher",
    27,
)

这是您的问题的基本解决方案。您可以通过多种方式优化它:

  • 专门为查询创建log.Logger,以便可以将其定向到特定的输出目标
  • 将上述log.Loggersql.DB对象 Package 在一个特殊的结构中,该结构将在查询完成时记录查询

下面是said结构体的一个粗略示例:

type DB struct {
    db *sql.DB
    dsn string
    log *log.Logger
}

func NewDB(driver, dsn string, log *log.Logger) (*DB, error) {
    db, err := sql.Open(driver, dsn)
    if err != nil {
        return nil, err
    }

    return &DB {
        db: db,
        dsn: dsn,
        log: log,
    }
}

func (d DB) Exec(query string, args ...interface{}) (sql.Result, err) {
    d.log.Println(dsn, query, args)
    return d.db.Exec(query, args...)
}

以及如何使用它:

l := log.New(os.Stdout, "[sql]", log.LstdFlags)

db, _ := NewDB(driver, dataSourceName, l)
result, _ := db.Exec(
    "INSERT INTO users (name, age) VALUES (?, ?)",
    "gopher",
    27,
)

显然,您可以通过添加错误报告、查询持续时间等来再次细化此设计。

sqyvllje

sqyvllje2#

现在有一个解决方案,不必用添加日志记录的 Package 器 Package sql.DB
sqldblogger有助于实现这一点,而无需更改现有的sql.DB代码。

相关问题