Golang 开发使用 gorm 时打印 SQL 语句

admin2024-09-04  11

目录

  • 1. 使用 Debug 方法
  • 2. 全局设置日志级别
  • 3. 自定义 Logger
  • 4. 总结

Gorm 有一个 默认 logger 实现,默认情况下,它会打印慢 SQL 和错误。如果想要全部或部分打印 SQL 的话可以通过设置日志级别和使用 Logger 接口来实现自定义处理。以下是一些方法来实现这个功能。

1. 使用 Debug 方法

GORM 提供了一个 Debug 方法,可以在链式调用中打印出生成的 SQL 语句和执行时间。

一般用于开发或者是线上排查某个问题时使用。

代码示例

package main

import (
    "fmt"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

type User struct {
    ID   int
    Name string
}

func main() {
    dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }

    var users []User
    // 使用 Debug() 方法
    db.Debug().Where("name = ?", "John").Find(&users)

    fmt.Println(users)
}

2. 全局设置日志级别

在 GORM 配置中设置 Logger,可以全局打印 SQL 语句。可以使用 gorm/logger 包来设置日志级别。

GORM 定义了这些日志级别:

  • Silent:不打印任何日志。
  • Error:仅打印错误日志。
  • Warn:打印警告和错误日志。
  • Info:打印所有日志(包括 SQL 语句和运行时间)

代码示例

package main

import (
    "log"
    "time"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "gorm.io/gorm/logger"
)

type User struct {
    ID   int
    Name string
}

func main() {
    dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    newLogger := logger.New(
        log.New(log.Writer(), "\r\n", log.LstdFlags), // io writer
        logger.Config{
            SlowThreshold: time.Second,   // 慢 SQL 阈值
            LogLevel:      logger.Info,   // 日志级别
            IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound(记录未找到)错误
            Colorful:      true,          // 启用彩色打印
        },
    )

    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
        Logger: newLogger,
    })
    if err != nil {
        panic("failed to connect database")
    }

    var users []User
    db.Where("name = ?", "John").Find(&users)

    fmt.Println(users)
}

3. 自定义 Logger

如果需要更复杂的日志逻辑,可以实现 gorm/logger 包中的 Interface 接口,来自定义 Logger。

代码示例

package main

import (
    "log"
    "time"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "gorm.io/gorm/logger"
    "gorm.io/gorm/utils"
)

type CustomLogger struct {
    logger.Interface
}

func (c *CustomLogger) Info(ctx context.Context, msg string, data ...interface{}) {
    log.Printf("[INFO] "+msg, data...)
}

func (c *CustomLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
    log.Printf("[WARN] "+msg, data...)
}

func (c *CustomLogger) Error(ctx context.Context, msg string, data ...interface{}) {
    log.Printf("[ERROR] "+msg, data...)
}

// 追踪并输出 sql 的详细信息:sql 语句、绑定的参数、执行时间等。
func (c *CustomLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
    elapsed := time.Since(begin)
    sql, rows := fc()
    log.Printf("[SQL] %s [rows:%d] [elapsed:%s] [error:%v]\n", sql, rows, elapsed, err)
}

func main() {
    dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    customLogger := &CustomLogger{}

    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
        Logger: customLogger,
    })
    if err != nil {
        panic("failed to connect database")
    }

    var users []User
    db.Where("name = ?", "John").Find(&users)

    fmt.Println(users)
}

4. 总结

通过上述方法,可以在 GORM 中实现 SQL 语句的打印,从而方便调试和监控数据库操作。根据具体需求,可以选择使用 Debug 模式、全局设置日志级别或者自定义 Logger

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!