記“gorm查詢沒報錯,但結果為空”的解決


解決方案在文末

問題引入

今天閑來無事,想要上手一下gorm,但是開始就碰壁了!

明明數據庫都連接成功了,但是...

代碼:

type Account struct {
	id int
	name string
	money float64
}

func main() {
	db, err := gorm.Open("mysql", "username:pswd@(127.0.0.1)/db?charset=utf8mb4&parseTime=True&loc=Local")
	db.SingularTable(true)
	defer db.Close()
	if err != nil {
		panic("failed to connect database")
	}
	var account Account
	var arr []Account
	fmt.Println(db.HasTable(account))
	db.Find(&arr)
	fmt.Println(arr)
}

運行結果:

true
[{0  0} {0  0} {0  0} {0  0}]

問題分析

我們可以確定的是:

  • 數據庫連接成功
  • 數據庫也確確實實是有account這張表
  • 能查出來我這張表有4條數據,有四個account對象,但就是值放不進去

怎么就查不出來呢???

根據上面可以推測,我們是能找到對應的對象關系的,但是就是值放不進去

俺以前是寫Java的,用過的ORM主要就是MyBatis,我極力的回想,總感覺就差一點點,算了,面向互聯網編程把,於是我去StackOverflow上逛了一下,果真找到了解決的方案!

在這里插入圖片描述

解決思路

首先明確我們的問題:我們找的到對應的對象,但是!【值】放不進去!

我們知道Go和Java一樣,是靜態語言,要做動態的特性,得靠多態、反射來提供,而我們這邊的gorm框架就是用了【反射】這一技術,找到相對應的數據行,通過類模板創建對象,再將列屬性一個個賦值進去再返回,問題就出在這里!!!

為什么放不進去?因為我把它給封裝了!!!

Go里面,是通過首字母的大小寫來控制封裝,大寫公開,小寫隱藏,而我在Java里小寫習慣了,這里也很自然的小寫了!而Java里我通常為了方便也會用Lombok插件,也就沒怎么寫過getter和setter,我的印象中Java雖然變量隱藏,但可以通過反射來拿出對象的set方法,把值裝進去,但是Go有沒有呢?我的猜測是沒有,因為很多庫里面,也並沒有使用這種方法,所以我的猜測是gorm也不會支持getter和setter這種東西

我們來看看官方的《Effective Go》是怎么說的:
在這里插入圖片描述

所以,變量被我給隱藏起來了,gorm自然值裝不進去了

解決過程

把首字母改為大寫:

type Account struct {
	Id int
	Name string
	Money float64
}

運行結果:

true
[{1 aaa 500} {2 bbb 1000} {3 ccc 1000} {4 張三 666}]

成了!

坑點

  • Go的反射機制
  • Go的封裝


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM