go1.14 windows/amd64 goFrame v1.11.4 Struct字段如果为指针类型,db.GetStructs()或者model.Structs()报错,结构体部分字段设置为指针的原因是,数据库里某些字段为NULL,例如下面的纬度字段是小数类型,但是数据库表的这个字段可以为NULL,查询会报错,因为float64无法设置为nil,它的零值是0。还有地址字段数据库表该字段为NULL时,结构体Addr字段映射的值是“”空字符串,期望得到的是nil,所以只能将这些可以为NULL的结构体字段设置为指针类型 例如:
type Test struct {
DeviceId string `orm:"device_id" json:"deviceId"`
Addr *string `orm:"addr" json:"addr"` //地址
Latitude *float64 `orm:"latitude" json:"latitude"` // 纬度
Longitude *float64 `orm:"longitude" json:"longitude"` // 经度
}
目前个人的解决方法是: 1.在gconv.go的Convert增加指针类型判断
func Convert(i interface{}, t string, params ...interface{}) interface{} {
switch t {
case "int":
return Int(i)
case "int8":
return Int8(i)
case "int16":
return Int16(i)
case "int32":
return Int32(i)
case "int64":
return Int64(i)
case "uint":
return Uint(i)
case "uint8":
return Uint8(i)
case "uint16":
return Uint16(i)
case "uint32":
return Uint32(i)
case "uint64":
return Uint64(i)
case "float32":
return Float32(i)
case "float64":
return Float64(i)
case "bool":
return Bool(i)
case "string":
return String(i)
case "*int":
if i==nil {
return i
}
r:=Int(i)
return &r
case "*int8":
if i==nil {
return i
}
r:=Int8(i)
return &r
case "*int16":
if i==nil {
return i
}
r:=Int16(i)
return &r
case "*int32":
if i==nil {
return i
}
r:=Int32(i)
return &r
case "*int64":
if i==nil {
return i
}
r:=Int64(i)
return &r
case "*uint":
if i==nil {
return i
}
r:=Uint(i)
return &r
case "*uint8":
if i==nil {
return i
}
r:=Uint8(i)
return &r
case "*uint16":
if i==nil {
return i
}
r:=Uint16(i)
return &r
case "*uint32":
if i==nil {
return i
}
r:=Uint32(i)
return &r
case "*uint64":
if i==nil {
return i
}
r:=Uint64(i)
return &r
case "*float32":
if i==nil {
return i
}
r:=Float32(i)
return &r
case "*float64":
if i==nil {
return i
}
r:=Float64(i)
return &r
case "*bool":
if i==nil {
return i
}
r:=Bool(i)
return &r
case "*string":
if i==nil {
return i
}
r:=String(i)
return &r
case "[]byte":
return Bytes(i)
case "[]int":
return Ints(i)
case "[]int32":
return Int32s(i)
case "[]int64":
return Int64s(i)
case "[]uint":
return Uints(i)
case "[]uint32":
return Uint32s(i)
case "[]uint64":
return Uint64s(i)
case "[]float32":
return Float32s(i)
case "[]float64":
return Float64s(i)
case "[]string":
return Strings(i)
case "Time", "time.Time":
if len(params) > 0 {
return Time(i, String(params[0]))
}
return Time(i)
case "gtime.Time":
if len(params) > 0 {
return GTime(i, String(params[0]))
}
return *GTime(i)
case "GTime", "*gtime.Time":
if len(params) > 0 {
return GTime(i, String(params[0]))
}
return GTime(i)
case "Duration", "time.Duration":
return Duration(i)
default:
return i
}
}
2.goconv_struct.go的方法bindVarToStructAttr里这一行
structFieldValue.Set(reflect.ValueOf(Convert(value, structFieldValue.Type().String())))改为
if v:=Convert(value, structFieldValue.Type().String());v!=nil {
structFieldValue.Set(reflect.ValueOf(v))
}
因为structFieldValue.Set(nil)
会报错
不知道这样改是否可行?
暂时未发现insert不支持指针类型字段,只有select不支持指针类型字段