Golang開發(fā)使用gorm時(shí)打印SQL語句方式
參考 gorm 文檔:https://gorm.io/zh_CN/docs/logger.html
Gorm 有一個(gè) 默認(rèn) logger 實(shí)現(xiàn),默認(rèn)情況下,它會(huì)打印慢 SQL 和錯(cuò)誤。
如果想要全部或部分打印 SQL 的話可以通過設(shè)置日志級(jí)別和使用 Logger 接口來實(shí)現(xiàn)自定義處理。
以下是一些方法來實(shí)現(xiàn)這個(gè)功能。
1. 使用 Debug 方法
GORM 提供了一個(gè) Debug 方法,可以在鏈?zhǔn)秸{(diào)用中打印出生成的 SQL 語句和執(zhí)行時(shí)間。
一般用于開發(fā)或者是線上排查某個(gè)問題時(shí)使用。
Debug 單個(gè)操作時(shí),會(huì)將當(dāng)前操作的 log 級(jí)別調(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è)置日志級(jí)別
在 GORM 配置中設(shè)置 Logger,可以全局打印 SQL 語句??梢允褂?gorm/logger 包來設(shè)置日志級(jí)別。
GORM 定義了這些日志級(jí)別:
Silent:不打印任何日志。Error:僅打印錯(cuò)誤日志。Warn:打印警告和錯(cuò)誤日志。Info:打印所有日志(包括 SQL 語句和運(yùn)行時(shí)間)
代碼示例:
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, // 日志級(jí)別
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound(記錄未找到)錯(cuò)誤
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ù)雜的日志邏輯,可以實(shí)現(xiàn) gorm/logger 包中的 Interface 接口,來自定義 Logger。
參考 GORM 的 默認(rèn) 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 的詳細(xì)信息:sql 語句、綁定的參數(shù)、執(zhí)行時(shí)間等。
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 中實(shí)現(xiàn) SQL 語句的打印,從而方便調(diào)試和監(jiān)控?cái)?shù)據(jù)庫操作。
根據(jù)具體需求,可以選擇使用 Debug 模式、全局設(shè)置日志級(jí)別或者自定義 Logger。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
在Go程序中實(shí)現(xiàn)服務(wù)器重啟的方法
這篇文章主要介紹了在Go程序中實(shí)現(xiàn)服務(wù)器重啟的方法,由于很多人盲目崇拜谷歌"親爹",Go語言在國(guó)內(nèi)有著不尋常的人氣,需要的朋友可以參考下2015-06-06
golang連接池檢查連接失敗時(shí)如何重試(示例代碼)
在Go中,可以通過使用database/sql包的DB類型的Ping方法來檢查數(shù)據(jù)庫連接的可用性,本文通過示例代碼,演示了如何在連接檢查失敗時(shí)進(jìn)行重試,感興趣的朋友一起看看吧2023-10-10
詳解Golang time包中的結(jié)構(gòu)體time.Time
在日常開發(fā)過程中,會(huì)頻繁遇到對(duì)時(shí)間進(jìn)行操作的場(chǎng)景,使用 Golang 中的 time 包可以很方便地實(shí)現(xiàn)對(duì)時(shí)間的相關(guān)操作,本文先講解一下 time 包中的結(jié)構(gòu)體 time.Time,需要的朋友可以參考下2023-07-07
關(guān)于golang監(jiān)聽rabbitmq消息隊(duì)列任務(wù)斷線自動(dòng)重連接的問題
這篇文章主要介紹了golang監(jiān)聽rabbitmq消息隊(duì)列任務(wù)斷線自動(dòng)重連接,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
Go語言使用slices包輕松實(shí)現(xiàn)排序功能
在 Go 語言開發(fā)中,對(duì)數(shù)據(jù)進(jìn)行排序是常見的需求,Go 1.18 版本引入的 slices包提供了簡(jiǎn)潔高效的排序解決方案,支持內(nèi)置類型和用戶自定義類型的排序操作,本文將通過具體示例,詳細(xì)介紹如何使用 slices包實(shí)現(xiàn)排序及相關(guān)功能,需要的朋友可以參考下2025-05-05

