golang mysql查詢textRows和binaryRows解惑
阿新 • • 發佈:2022-12-09
1. 問題之前寫了一套統一mysql返回資料的解析庫:
rows, err := ms.dbInst.Query(s, args...) //執行SQL語句,比如select * from users if err != nil { panic(err) } columns, err := rows.Columns() //獲取列的資訊 if err != nil { panic(err) } colTypes, err := rows.ColumnTypes() if err != nil { panic(err) } count := len(columns) //列的數量 var values = make([] interface {}, count) //建立一個與列的數量相當的空介面 for i := range values { var ii interface {} //為空介面分配記憶體 values[i] = &ii //取得這些記憶體的指標,因後繼的Scan函式只接受指標 } ret := make([] map [string] interface {}, 0) //建立返回值:不定長的map型別切片 for rows.Next() { err := rows.Scan(values...) //開始讀行,Scan函式只接受指標變數 m := make( map [string] interface {}) //用於存放1列的 [鍵/值] 對 if err != nil { panic(err) } for i, colName := range columns { //讀出raw資料,型別不一定為byte,parseTime=true 時時間型別會被轉化為 time.Time var rawValue = *(values[i].(* interface {}))if rawValue == nil { // 如果資料查詢到是nil,預設返回nil m[colName] = nil continue } m[colName] = NewValueTransferor(colTypes[i].DatabaseTypeName()).Deserialize(rawValue) } ret = append(ret, m) //將單行所有列的鍵值對附加在總的返回值上(以行為單位) }
2. 針對不同的查詢方式得到的rawValue值是不一樣的:
引數在sql裡面的查詢:
sql3 := `select user_id from auth_order_user where order_no = 111 ` res3 := model2.Query(sql3) fmt.Println(res3) 結果是uint8型別:引數不在sql裡面的查詢:
sql2 := `select user_id from auth_order_user where order_no = ? ` res2 := model2.Query(sql2, "111") fmt.Println(res2)結果是int64:
3. 分析:
在query的時候,如果不帶引數,走的是textRows;而帶引數則返回,在外面跟蹤的話,可以發現走的是binaryRows
textRows對返回值的解析是這樣的:
可以發現只解析time型別,其他什麼都不做
而binaryRows對返回值的解析是這樣的:
會根據不同型別進行解析,整形解析成整形