背景:
gorm开启了日志,有个表存储大的二进制数据,导致日志文件很大,而且二进制导致乱码。
需求:
屏蔽这个表的sql日志,不要影响其他表的sql日志。
实验:
gorm_log.go
Go
package main
import (
"context"
"database/sql"
"fmt"
"log"
"net/url"
"gorm.io/gorm/logger"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type Params struct {
Id int64 `gorm:"id" json:"id"`
Key string `gorm:"key" json:"key"`
Value string `gorm:"value" json:"value"`
}
func (Params) TableName() string {
return "params"
}
func main() {
encodedPassword := url.QueryEscape("mypassword")
dsn := "root:" + encodedPassword + "@tcp(127.0.0.1:3306)/mydbname?charset=utf8mb4&parseTime=True&loc=Local"
//fmt.Println(dsn)
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, // 启用彩色打印
},
)
gormDB, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: newLogger,
})
if err != nil {
log.Fatal(err)
}
sqlDB, err := gormDB.DB()
if err != nil {
log.Fatal(err)
}
// 常规的gorm用法
fmt.Println("--- gorm start ---")
var params Params
sqlResult := gormDB.First(¶ms, 1)
if sqlResult.Error != nil {
log.Fatal(sqlResult.Error)
}
fmt.Println(params)
fmt.Println("--- gorm end ---")
// gorm.DB使用原生SQL查询
fmt.Println("--- gorm.DB with raw sql start ---")
var result struct {
Count int
}
err = gormDB.Raw("SELECT COUNT(*) as count FROM params").Scan(&result.Count).Error
if err != nil {
log.Fatal(err)
}
fmt.Printf("count: %d\n", result.Count)
fmt.Println("--- gorm.DB with raw sql end ---")
// sql.DB使用原生SQL查询
fmt.Println("--- sql.DB with raw sql start ---")
err = sqlDB.QueryRow("SELECT COUNT(*) as count FROM params").Scan(&result.Count)
if err != nil {
log.Fatal(err)
}
fmt.Printf("count: %d\n", result.Count)
fmt.Println("--- sql.DB with raw sql end ---")
// 使用真正的原生SQL(不依赖GORM)
fmt.Println("--- golang raw sql start ---")
useNativeSQL(sqlDB)
fmt.Println("--- golang raw sql end ---")
// 直接使用日志方法自己打印日志
fmt.Println("--- gorm log start ---")
gormDB.Logger.Info(context.TODO(), "gorm log is here")
fmt.Println("--- gorm log end ---")
}
func useNativeSQL(db *sql.DB) {
rows, err := db.Query("SELECT `key`, value FROM params limit 3")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var key, value string
err = rows.Scan(&key, &value)
if err != nil {
log.Fatal(err)
}
fmt.Printf("key: %s, value: %s\n", key, value)
}
if err = rows.Err(); err != nil {
log.Fatal(err)
}
}
运行:
bash
go mod init gormtest
go mod tidy
go run gorm_log.go
输出:

结论:
1、gorm常规用法和通过grom.DB的原生用法都会有日志。
2、通过gorm获取sql.DB然后执行原生sql不会有日志。
3、通过gorm获取sql.DB然后使用golang的原生sql写法不会有日志。
4、通过gormDB.Logger可以自己打印出类似形式的日志。
--end--