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对返回值的解析是这样的:
会根据不同类型进行解析,整形解析成整形
标签:rows,err,nil,textRows,golang,binaryRows,values,interface,解析 From: https://www.cnblogs.com/zhanchenjin/p/16969511.html