Golang開發(fā)使用gorm時打印SQL語句方式
參考 gorm 文檔:https://gorm.io/zh_CN/docs/logger.html
Gorm 有一個 默認 logger 實現(xiàn),默認情況下,它會打印慢 SQL 和錯誤。
如果想要全部或部分打印 SQL 的話可以通過設(shè)置日志級別和使用 Logger 接口來實現(xiàn)自定義處理。
以下是一些方法來實現(xiàn)這個功能。
1. 使用 Debug 方法
GORM 提供了一個 Debug 方法,可以在鏈式調(diào)用中打印出生成的 SQL 語句和執(zhí)行時間。
一般用于開發(fā)或者是線上排查某個問題時使用。
Debug 單個操作時,會將當前操作的 log 級別調(diào)整為 logger.Info
代碼示例:
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. 全局設(shè)置日志級別
在 GORM 配置中設(shè)置 Logger,可以全局打印 SQL 語句??梢允褂?gorm/logger 包來設(shè)置日志級別。
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
如果需要更復(fù)雜的日志邏輯,可以實現(xiàn) gorm/logger 包中的 Interface 接口,來自定義 Logger。
參考 GORM 的 默認 logger 來定義您自己的 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 語句、綁定的參數(shù)、執(zhí)行時間等。
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)
}總結(jié)
通過上述方法,可以在 GORM 中實現(xiàn) SQL 語句的打印,從而方便調(diào)試和監(jiān)控數(shù)據(jù)庫操作。
根據(jù)具體需求,可以選擇使用 Debug 模式、全局設(shè)置日志級別或者自定義 Logger。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
go-micro開發(fā)RPC服務(wù)以及運行原理介紹
這篇文章介紹了go-micro開發(fā)RPC服務(wù)的方法及其運行原理,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07

