一,安装第三方库:
$ go get -u gorm.io/gorm
go: added github.com/jinzhu/inflection v1.0.0
go: added github.com/jinzhu/now v1.1.5
go: added gorm.io/gorm v1.25.12
$ go get -u gorm.io/driver/mysql
go: added filippo.io/edwards25519 v1.1.0
go: added github.com/go-sql-driver/mysql v1.8.1
go: added gorm.io/driver/mysql v1.5.7
二,代码:
1,global/dblink.go
package globalimport ("fmt""github.com/gin-gonic/gin""gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger""runtime""runtime/debug""time"
)var (DBLink *gorm.DB
)func SetupDBLink() (error) {var err errordsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=%s&parseTime=%t&loc=Local","root","rootpassword","127.0.0.1:3306","gysy","utf8",true, )DBLink, err = gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: logger.Default.LogMode(logger.Info),})if err != nil {return err}sqlDB, _ := DBLink.DB()// SetMaxIdleConns 设置空闲连接池中连接的最大数量sqlDB.SetMaxIdleConns(10)// SetMaxOpenConns 设置打开数据库连接的最大数量sqlDB.SetMaxOpenConns(30)// SetConnMaxLifetime 设置了连接可复用的最大时间sqlDB.SetConnMaxLifetime(time.Hour)//"query:before"DBLink.Callback().Create().Register("create:before", func(db *gorm.DB) {fmt.Println("==================create:create======================")c, ok := db.Statement.Context.(*gin.Context)if ok {fmt.Println("转换成功")}url:=c.Request.URL.String()fmt.Println("url:",url)timeStr := time.Now().Format("2006-01-02 15:04:05")fmt.Println("当前时间:", timeStr)fmt.Println("当前访问path:", c.FullPath())fmt.Println("当前完整地址:", c.Request.URL.String())fmt.Println("当前协议:", c.Request.Proto)fmt.Println("当前get参数:",GetAllGetParams(c))fmt.Println("当前post参数:",GetAllPostParams(c))fmt.Println("当前访问方法:", c.Request.Method)fmt.Println("当前访问Host:", c.Request.Host)fmt.Println("当前IP:",c.ClientIP())fmt.Println("当前浏览器:",c.Request.UserAgent())if db.Error == nil { // 只打印成功的查询//db.Statement.SQL.sql, values := db.Statement.SQL.String(), db.Statement.Varsfmt.Println("sql:",sql)fmt.Println("values:",values)} else {var pc [1]uintptrruntime.Callers(4, pc[:]) // 获取调用者的位置,4 表示跳过 logError 和当前函数本身f := runtime.FuncForPC(pc[0])file, line := f.FileLine(pc[0])fmt.Printf("Error at %s:%d - %v\n", file, line, db.Error)sql, values := db.Statement.SQL.String(), db.Statement.Varsfmt.Println("sql:",sql)fmt.Println("values:",values)fmt.Println("dblink中:查询前发生错误:",db.Error)fmt.Println("dblink:stack打印开始")fmt.Println(string(debug.Stack()))fmt.Println("dblink:stack打印结束")}})DBLink.Callback().Query().Register("query:before", func(db *gorm.DB) {fmt.Println("==================query:before======================")c, ok := db.Statement.Context.(*gin.Context)if ok {fmt.Println("转换成功")}url:=c.Request.URL.String()fmt.Println("url:",url)timeStr := time.Now().Format("2006-01-02 15:04:05")fmt.Println("当前时间:", timeStr)fmt.Println("当前访问path:", c.FullPath())fmt.Println("当前完整地址:", c.Request.URL.String())fmt.Println("当前协议:", c.Request.Proto)fmt.Println("当前get参数:",GetAllGetParams(c))fmt.Println("当前post参数:",GetAllPostParams(c))fmt.Println("当前访问方法:", c.Request.Method)fmt.Println("当前访问Host:", c.Request.Host)fmt.Println("当前IP:",c.ClientIP())fmt.Println("当前浏览器:",c.Request.UserAgent())fmt.Println("报错:",db.Error)if db.Error == nil { // 只打印成功的查询//db.Statement.SQL.sql, values := db.Statement.SQL.String(), db.Statement.Varsfmt.Println("sql:",sql)fmt.Println("values:",values)} else {var pc [1]uintptrruntime.Callers(4, pc[:]) // 获取调用者的位置,4 表示跳过 logError 和当前函数本身f := runtime.FuncForPC(pc[0])file, line := f.FileLine(pc[0])fmt.Printf("Error at %s:%d - %v\n", file, line, db.Error)sql, values := db.Statement.SQL.String(), db.Statement.Varsfmt.Println("sql:",sql)fmt.Println("values:",values)fmt.Println("dblink中:查询前发生错误:",db.Error)fmt.Println("dblink:stack打印开始")fmt.Println(string(debug.Stack()))fmt.Println("dblink:stack打印结束")}})DBLink.Callback().Update().Register("update:before", func(db *gorm.DB) {fmt.Println("==================update:before======================")c, ok := db.Statement.Context.(*gin.Context)if ok {fmt.Println("转换成功")}url:=c.Request.URL.String()fmt.Println("url:",url)timeStr := time.Now().Format("2006-01-02 15:04:05")fmt.Println("当前时间:", timeStr)fmt.Println("当前访问path:", c.FullPath())fmt.Println("当前完整地址:", c.Request.URL.String())fmt.Println("当前协议:", c.Request.Proto)fmt.Println("当前get参数:",GetAllGetParams(c))fmt.Println("当前post参数:",GetAllPostParams(c))fmt.Println("当前访问方法:", c.Request.Method)fmt.Println("当前访问Host:", c.Request.Host)fmt.Println("当前IP:",c.ClientIP())fmt.Println("当前浏览器:",c.Request.UserAgent())if db.Error == nil { // 只打印成功的查询//db.Statement.SQL.sql, values := db.Statement.SQL.String(), db.Statement.Varsfmt.Println("sql:",sql)fmt.Println("values:",values)} else {var pc [1]uintptrruntime.Callers(4, pc[:]) // 获取调用者的位置,4 表示跳过 logError 和当前函数本身f := runtime.FuncForPC(pc[0])file, line := f.FileLine(pc[0])fmt.Printf("Error at %s:%d - %v\n", file, line, db.Error)sql, values := db.Statement.SQL.String(), db.Statement.Varsfmt.Println("sql:",sql)fmt.Println("values:",values)fmt.Println("dblink中:查询前发生错误:",db.Error)fmt.Println("dblink:stack打印开始")fmt.Println(string(debug.Stack()))fmt.Println("dblink:stack打印结束")}})return nil
}
2,service/articleService.go
注意用 withContext传递*gin.Context
package serviceimport ("fmt""github.com/gin-gonic/gin""imagebank/global""imagebank/model"
)
//select一个article
func GetOneArticleById(c *gin.Context,id int) (*model.ArticleModel, error) {fields := []string{"id", "title","demo","content1"}articleOne:=&model.ArticleModel{}err := global.DBLink.WithContext(c).Select(fields).Where("id=?",id).First(&articleOne).Errorif (err != nil) {fmt.Println("service:发生了错误:")fmt.Println(err)return nil,err} else {return articleOne,nil}
}//add一个article
func InsertOneArticle(c *gin.Context,articleOne model.ArticleModel) (uint,error) {result := global.DBLink.WithContext(c).Create(&articleOne)return articleOne.Id,result.Error
}
三,测试效果:
新加一行数据:
转换成功
url: /image/add
当前时间: 2025-02-02 12:32:46
当前访问path: /image/add
当前完整地址: /image/add
当前协议: HTTP/1.1
当前get参数:
当前post参数: key:cid,value:123
key:title,value:12当前访问方法: POST
当前访问Host: 192.168.219.3:8080
当前IP: 192.168.219.1
当前浏览器: PostmanRuntime/7.43.0
Error at /data/goapp/imagebank/service/articleService.go:28 - Error 1062 (23000): Duplicate entry '1000' for key 'zr_article.PRIMARY'
sql: INSERT INTO `zr_article` (`title`,`demo`,`content`,`id`) VALUES (?,?,?,?)
values: [aaaa bbbb cccc 1000]
dblink中:查询前发生错误: Error 1062 (23000): Duplicate entry '1000' for key 'zr_article.PRIMARY'
dblink:stack打印开始
12:32:46 app | goroutine 6 [running]:
runtime/debug.Stack()/usr/local/soft/go/src/runtime/debug/stack.go:26 +0x5e
imagebank/global.SetupDBLink.func1(0xc000277ef0)/data/goapp/imagebank/global/dblink.go:82 +0xaab
gorm.io/gorm.(*processor).Execute(0xc0002426e0, 0xc000277b00?)/data/gopath/pkg/mod/gorm.io/gorm@v1.25.12/callbacks.go:130 +0x3cb
gorm.io/gorm.(*DB).Create(0xc000162eb8?, {0x983d60, 0xc00024ab80})/data/gopath/pkg/mod/gorm.io/gorm@v1.25.12/finisher_api.go:24 +0xa8
imagebank/service.InsertOneArticle(0xc000146600, {0x3e8, {0xa27a30, 0x4}, {0xa27a34, 0x4}, {0xa27a38, 0x4}})/data/goapp/imagebank/service/articleService.go:27 +0xbc
imagebank/controller.(*ImageController).Add(0xc000162fe0?, 0xc000146600)/data/goapp/imagebank/controller/ImageController.go:47 +0x90
github.com/gin-gonic/gin.(*Context).Next(0xc000146600)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185 +0x2b
imagebank/routes.Routes.AccessLog.func2(0xc000146600)/data/goapp/imagebank/middleware/accesslog.go:84 +0x2ba
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
imagebank/routes.Recover(0xc000146600)/data/goapp/imagebank/routes/routes.go:87 +0x5c
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc000146600)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/recovery.go:102 +0x6f
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc000146600)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/logger.go:249 +0xe5
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc0000a6000, 0xc000146600)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/gin.go:633 +0x892
github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc0000a6000, {0xb1c030, 0xc00019e1c0}, 0xc0000c4000)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/gin.go:589 +0x1b2
net/http.serverHandler.ServeHTTP({0xb19f30?}, {0xb1c030?, 0xc00019e1c0?}, 0x6?)/usr/local/soft/go/src/net/http/server.go:3210 +0x8e
net/http.(*conn).serve(0xc0000be000, {0xb1d070, 0xc000096390})/usr/local/soft/go/src/net/http/server.go:2092 +0x5d0
created by net/http.(*Server).Serve in goroutine 1/usr/local/soft/go/src/net/http/server.go:3360 +0x48512:32:46 app | dblink:stack打印结束
查询数据:
12:29:33 app | ==================query:before======================
转换成功
url: /image/detail?id=123
当前时间: 2025-02-02 12:29:33
当前访问path: /image/detail
当前完整地址: /image/detail?id=123
当前协议: HTTP/1.1
当前get参数: key:id,value:123当前post参数:
当前访问方法: GET
当前访问Host: 192.168.219.3:8080
当前IP: 192.168.219.1
当前浏览器: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36
报错: Error 1054 (42S22): Unknown column 'content1' in 'field list'
Error at /data/goapp/imagebank/service/articleService.go:14 - Error 1054 (42S22): Unknown column 'content1' in 'field list'
sql: SELECT `id`,`title`,`demo`,content1 FROM `zr_article` WHERE id=? ORDER BY `zr_article`.`id` LIMIT ?
values: [21 1]
dblink中:查询前发生错误: Error 1054 (42S22): Unknown column 'content1' in 'field list'
dblink:stack打印开始
12:29:33 app | goroutine 5 [running]:
runtime/debug.Stack()/usr/local/soft/go/src/runtime/debug/stack.go:26 +0x5e
imagebank/global.SetupDBLink.func1(0xc0000942d0)/data/goapp/imagebank/global/dblink.go:124 +0xb2b
gorm.io/gorm.(*processor).Execute(0xc000242730, 0xc000277b00?)/data/gopath/pkg/mod/gorm.io/gorm@v1.25.12/callbacks.go:130 +0x3cb
gorm.io/gorm.(*DB).First(0xc000094240?, {0x9608a0, 0xc00005a010}, {0x0, 0x0, 0x0})/data/gopath/pkg/mod/gorm.io/gorm@v1.25.12/finisher_api.go:129 +0x1b2
imagebank/service.GetOneArticleById(0xc00009a500, 0x15)/data/goapp/imagebank/service/articleService.go:14 +0x1b1
imagebank/controller.(*ImageController).Detail(0xc00015efe0?, 0xc00009a500)/data/goapp/imagebank/controller/ImageController.go:79 +0x27
github.com/gin-gonic/gin.(*Context).Next(0xc00009a500)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185 +0x2b
imagebank/routes.Routes.AccessLog.func2(0xc00009a500)/data/goapp/imagebank/middleware/accesslog.go:84 +0x2ba
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
imagebank/routes.Recover(0xc00009a500)/data/goapp/imagebank/routes/routes.go:87 +0x5c
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0xc00009a500)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/recovery.go:102 +0x6f
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc00009a500)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/logger.go:249 +0xe5
github.com/gin-gonic/gin.(*Context).Next(...)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc000167040, 0xc00009a500)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/gin.go:633 +0x892
github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc000167040, {0xb1bb90, 0xc0000b0000}, 0xc00009e000)/data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.0/gin.go:589 +0x1b2
net/http.serverHandler.ServeHTTP({0xc0000940c0?}, {0xb1bb90?, 0xc0000b0000?}, 0x6?)/usr/local/soft/go/src/net/http/server.go:3210 +0x8e
net/http.(*conn).serve(0xc000096000, {0xb1cbd0, 0xc0002d6120})/usr/local/soft/go/src/net/http/server.go:2092 +0x5d0
created by net/http.(*Server).Serve in goroutine 1/usr/local/soft/go/src/net/http/server.go:3360 +0x485dblink:stack打印结束