解決Gorm中使用Count后關聯查詢失效的問題

解決Gorm中使用Count后關聯查詢失效的問題

問題描述

當我們 在go中使用gorm進行多表join關聯查詢的時候

如果還有分頁的需求

那么可能會是這樣寫

package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"ormLogger "gorm.io/gorm/logger""time"
)func main() {type Detail struct {UesrId int    `json:"user_id"` // 自增 idAge    int    `json:"age"`     // 年齡Email  string `json:"email"`   // 郵箱}type User struct {Id     int    `json:"id" gorm:"primaryKey"` // 自增 idName   string `json:"name"`                 // 名字Detail `gorm:"foreignKey:UesrId"`}type MysqlConfig struct {MysqlUrl     stringLogger       ormLogger.WriterMaxIdleCount intMaxOpen      intMaxLifetime  time.DurationLogLevel     ormLogger.LogLevel}var c MysqlConfigDB, err := gorm.Open(mysql.Open(c.MysqlUrl))if err != nil {panic("GORM 連接失敗," + err.Error())}tx := DB.Model(&User{}).Joins("Detail")var count int64tx.Count(&count)var data []Usertx.Limit(GetLimit()).Offset(GetOffset()).Find(&data)}

這樣count會計算出值,
而 再查詢數據就 會出現數據為空的情況

問題分析:

打印sql出來

SELECT count(*) FROM `users` SELECT `users`.`id`,`users`.`name`,`users`.`uesr_id`,`users`.`age`,`users`.`email` FROM `users` Detail LIMIT 1 OFFSET 3

通過查詢Count方法的源碼我們發現

tx.Statement.AddClause(clause.Select{Expression: clause.Expr{SQL: "count(*)"}})

這里如果調用count方法,gorm會把你的sql的select的字段轉換成 count*
所以,通過join關聯查詢的方式不可以進行對應字段的映射了

解決思路

我們執行查詢和執行記數的tx,使用兩個就好了
因為go語言是引用類型傳遞,所以該怎么進行拷貝tx對象呢

查詢gorm相關源碼發現,session()的源碼里包含

// Session create new db session
func (db *DB) Session(config *Session) *DB {var (txConfig = *db.Configtx       = &DB{Config:    &txConfig,Statement: db.Statement,Error:     db.Error,clone:     1,})if config.Context != nil || config.PrepareStmt || config.SkipHooks {tx.Statement = tx.Statement.clone()tx.Statement.DB = tx}
func (stmt *Statement) clone() *Statement {copy(newStmt.Joins, stmt.Joins)...// 在這里執行了copy方法
}

所以我們可以利用gorm中的session功能深拷貝一個 tx對象,即:tx2 := tx.session()

package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"ormLogger "gorm.io/gorm/logger""time"
)func main() {type Detail struct {UesrId int    `json:"user_id"` // 自增 idAge    int    `json:"age"`     // 年齡Email  string `json:"email"`   // 郵箱}type User struct {Id     int    `json:"id" gorm:"primaryKey"` // 自增 idName   string `json:"name"`                 // 名字Detail `gorm:"foreignKey:UesrId"`}type MysqlConfig struct {MysqlUrl     stringLogger       ormLogger.WriterMaxIdleCount intMaxOpen      intMaxLifetime  time.DurationLogLevel     ormLogger.LogLevel}var c MysqlConfigDB, err := gorm.Open(mysql.Open(c.MysqlUrl))if err != nil {panic("GORM 連接失敗," + err.Error())}tx := DB.Model(&User{}).Joins("Detail")tx2 := tx.Session(&gorm.Session{})var count int64tx2.Count(&count)var data []Usertx.Limit(GetLimit()).Offset(GetOffset()).Find(&data)分別打印出內存地址print(tx)	// 0x14000282150print(tx2)	// 0x140002821e0
}

這樣通過gorm中的session可以深拷貝出一個 gorm對象
執行Count后再執行查詢不會受影響

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/455003.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/455003.shtml
英文地址,請注明出處:http://en.pswp.cn/news/455003.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

hdu1540/poj2892 線段數區間合并

HDU - 1540 POJ - 2892 題意:n個點,有3種操作D a表示摧毀a這個點,R 表示修復上一個點,Q x表示查詢x所在的區間沒被摧毀的連續最大區間 思路:線段樹區間合并,區間合并主要就是對lsum rsum 和sum的動態維護&…

基于51單片機的交通燈控制設計

課程設計任務書及成績 課程名稱 單片機課程設計 題目 交通燈控制設計 課程設計目標與任務、計劃與進度安排: 實踐教學要求與任務: 1、了解交通燈的基本工作原理; 2、用Proteus模擬實現交通燈控制; 3、用Keil C51編程實現上述功能; 4、…

福斯i6飛行模式設置_數據網絡卡的時候,不妨試試“開關飛行模式”?上網速度明顯變快...

相信大家都有過這種經歷,手機數據網速很慢的時候,開一下飛行模式再關閉,上網速度會比之前快很多,這就有人有了疑問,為什么呢?開飛行模式再關掉飛行模式,其實等于是完成了一次手動的小區重選。移…

安裝開源 ITIL 門戶 iTOP

在 CentOS 7 上部署iTOP是一個簡單的基于Web的開源IT服務管理工具。它有所有的ITIL功能,包括服務臺、配置管理、事件管理、問題管理、變更管理和服務管理。iTOP依賴于Apache/IIS、MySQL和PHP,因此它可以運行在任何支持這些軟件的操作系統中。因為iTOP是一…

基于FPGA 的8b10b編解碼電路前端電路設計

基于FPGA 的8b10b編解碼電路前端電路設計 摘 要 本設計是采用EDA技術設計的一種8B /10B 編解碼電路,實現了在高速的串行數據傳輸中的直流平衡。該編解碼電路設計大體上可以由五個模塊構成,分別是默認編碼模塊、差異度計算模塊、編碼校正模塊、并串轉換模塊、顯示模…

day15(mysql 的多表查詢,事務)

mysql之多表查詢 1.合并結果集 作用:合并結果集就是把兩個select語句查詢的結果連接到一起! /*創建表t1*/ CREATE TABLE t1(a INT PRIMARY KEY ,b VARCHAR(10) ) INSERT INTO t1 VALUES(1,a); INSERT INTO t1 VALUES(2,b); INSERT INTO t1 VALUES(3,c); /*創建t2*/…

vue router傳參_新手使用vue-router傳參時注意事項

1. 使用name和params組合傳參this.$router.push({name: details, params: {id: 233}})路由配置import Vue from vueimport Router from vue-router Vue.use(Router) export default new Router({ mode: history, routes: [ { path: /details, name: details, component: resolv…

FFMpeg分析詳細分析

與其說是分析,不如說是學習,只是看在自己第一次寫系列文章的份上,給足自己面子,取個有"深度"的題目!如有人被題目所蒙騙進來,還望見諒! URLProtocol,URLContext和ByteIOContext是FFMp…

《jQuery基礎》總結

目前,互聯網上最好的jQuery入門教材,是Rebecca Murphey寫的《jQuery基礎》(jQuery Fundamentals)。這本書雖然是入門教材,但也足足有100多頁。我對它做了一個詳細的筆記,試圖理清jQuery的設計思想&#xff…

邏輯綜合工具DesignCompiler使用教程

邏輯綜合工具Design Compiler使用教程 圖形界面design vision操作示例 邏輯綜合主要是將HDL語言描述的電路轉換為工藝庫器件構成的網表的過程。綜合工具目前比較主流的是synopsys公司Design Compiler,我們在設計實踐過程中采用這一工具。Design compiler有兩種工作…

遍歷結構體_三菱ST語言編程(3)——結構體變量

上篇文章介紹了數組,是一組相同類型數據的列表,那么不同類型的數據能否組合到一起用一個標簽表示呢?答案當然是可以的,而實現這個功能的就是結構體(struct)。建立結構體在三菱結構化編程的界面中左側程序部件里可以找到結構體標簽…

關于微信小程序swiper的問題

關于小程序swiper的問題 代碼 在官方示例上給swiper添加了currentbindchangecircular添加了一個buttonbindtap用于切換下一張 index.wxml <swiper indicator-dots"{{indicatorDots}}"bindchange"swiperChange"current"{{index}}"circular&quo…

PyQt5案例匯總(完整版)

個人博客點這里 PyQt5案例匯總(完整版) 起步 PyQt5是一套綁定Qt5的應用程序框架。他在Python 2.x和3.x中都是可用的。該教程使用的是Python3.x。 Qt庫是一套最有用的GUI庫。 PyQt5是作為一套Python模塊實現的。他已經超過620個類和6000個函數與方法。他是一個運行在所有主…

中的 隱藏鼠標菜單_Mac移動隱藏刪除頂部菜單欄圖標教程

蘋果菜單欄貫穿 Mac 的屏幕頂部。左側是蘋果菜單和應用菜單&#xff0c;應用菜單一般顯示你當前使用的Mac軟件的所有功能菜單。右側通常是以圖標顯示的狀態菜單&#xff0c;幫助你快速查看Mac的狀態以及快速訪問某些Mac軟件。移動圖標位置若想要重新排列狀態菜單欄的圖標&#…

可以用什么代替平面鏡

答案是鏡面 潛望鏡是利用平面鏡來改變光路轉載于:https://www.cnblogs.com/lidepeng/p/7280593.html

[hadoop] kettle spoon 基礎使用 (txt 內容抽取到excel中)

spoon.bat 啟動kettle。 測試數據 1. 新建轉換 輸入中選擇文本文件輸入 雙擊設置文本輸入 字符集、分隔符設置 獲取對應的字段&#xff0c;預覽記錄。 拖入 excel輸出&#xff0c;設置轉換關系 設置輸出路徑 獲取字段 啟動轉換 導入的excel數據&#xff08;設置好格式,圖中ID,A…

ffmpeg提取音頻播放器總結

ffmpeg提取音頻播放器總結&#xff1b; 一&#xff1a;簡介 從編寫音頻播放器代碼到完成播放器編寫&#xff0c;測試&#xff0c;整整5天的時間&#xff0c;這時間還不算之前對 ffmpeg熟悉的時間&#xff0c;可以說是歷經千辛萬苦&#xff0c;終于搞出來了&#xff0c;雖然最…

【BZOJ 4103】 [Thu Summer Camp 2015]異或運算 可持久化01Trie

我們觀察數據&#xff1a;樹套樹 PASS 主席樹 PASS 一層一個Trie PASS 再看&#xff0c;異或&#xff01;我們就把目光暫時定在01Tire然后我們發現&#xff0c;我們可以帶著一堆點在01Trie上行走&#xff0c;因為O(n*q*30m*30)是一個可選復雜度。 我們想一下我們正常的時候…

Docker學習筆記——Java及Tomcat Dockerfile

1、Java Dockerfile創建項目目錄java&#xff0c;目錄下上傳所需java版本壓縮包&#xff0c;并創建Dockerfile文件&#xff0c;項目結構如下&#xff1a;java-Dockerfile-jdk-8u111-linux-x64.gzDockerfile內容&#xff1a;# JAVA # Version 1.8.0_111 # SOURCE_IMAGE FROM cen…

rabbitmq接口異常函數方法_RabbitMQ監控(三):監控隊列狀態

#RabbitMQ 監控(三)驗證RabbitMQ健康運行只是確保消息通信架構可靠性的一部分&#xff0c;同時&#xff0c;你也需要確保消息通信結構配置沒有遭受意外修改&#xff0c;從而避免應用消息丟失。RabbitMQ Management HTTP API提供了一個方法允許你查看任何vhost上的任何隊列&…