在 Go 中使用从 Gorm 查询的指针操作结构?
Manipulate struct with pointers queried from Gorm in Go?
我正在通过使用 Gqlgen 和 Gorm(postgres 方言)开发一个用 Go 编写的 Web 服务器来练习。
我首先描述了我的用户模型:
# dbm.User{}
type User struct {
BaseModel
Email string `gorm:"not null;unique_index:idx_email"`
UserID *string // External user ID
Name *string
NickName *string
FirstName *string
LastName *string
Location *string `gorm:"size:1048"`
Description *string `gorm:"size:1048"`
}
在这种情况下,据我所知,在我的结构中为某些值使用指针是很好的,因为当没有附加值时它们可以评估为 <nil>
。而如果我不使用指针,如果没有附加任何值,则 int 将为 0。好吧,这是有道理的……如果我没记错的话……
但是,我现在面临的困难是从数据库上的 Gorm 操作中获取此值时:
dbRecord := &dbm.User{}
db = db.Where(whereEmail, email).Find(&dbRecord)
fmt.Println("dbRecord:", dbRecord)
// Prints:
// dbRecord: &{{def90b3c-93ff-40f0-8d33-6320dddbe3f2 2019-10-01 14:16:34.365395 +0200 CEST 2019-10-01 14:16:34.365395 +0200 CEST} test@test.com <nil> 0xc0000a1cb0 0xc0000a1cd0 0xc0000a1cc0 <nil> 0xc0000a1cf0 0xc0000a1ce0}
这段代码查询了一个用户,其中email是"email@email.com",显然结构中的一些字段指向了值的实际地址。这是有道理的,但是如果我要读取这些数据就很烦人了。有读取这些数据的常规方法吗?
我尝试的是将此结构转换为 GQL 结构(由 GQLgen 自动生成):
# gqlm.User{}
type User struct {
ID string `json:"id"`
Email string `json:"email"`
UserID *string `json:"userId"`
Name *string `json:"name"`
FirstName *string `json:"firstName"`
LastName *string `json:"lastName"`
NickName *string `json:"nickName"`
Description *string `json:"description"`
Location *string `json:"location"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt *time.Time `json:"updatedAt"`
}
但是,当我需要值时,我又得到了地址,这是有道理的。
所以我找到的唯一方法是创建一个新的自定义结构 customUser,编组来自 Gorm 的数据,然后将其解组到我的 customUser 结构中:
type customUser struct {
ID string `json:"id"`
Email string `json:"email"`
UserID string `json:"userId"`
Name string `json:"name"`
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
NickName string `json:"nickName"`
Description string `json:"description"`
Location string `json:"location"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
bs, _ := json.Marshal(record)
var s = string(bs)
newRecord := &customUser{}
bs = []byte(s) // This is maybe not necessary
err = json.Unmarshal(bs, newRecord)
if err != nil {
fmt.Println(err)
}
fmt.Printf("record: %+v\n", newRecord)
// I now get the right format: record: &{ID:def90b3c-93ff-40f0-8d33-6320dddbe3f2 Email:test@test.com UserID: Name:frer FirstName:fwef LastName: NickName:trgt Description:werfergh rthrt hr Location:wfwf CreatedAt:2019-10-01 14:16:34.365395 +0200 CEST UpdatedAt:2019-10-01 14:16:34.365395 +0200 CEST}
但这似乎太过分了,如果我每次需要从数据库读取数据时都需要创建这样的结构,那么需要付出很多努力。这是要走的路吗?或者你知道更方便的方法吗?
您需要对字符串指针类型使用 sql.NullString。
请参阅https://golang.org/pkg/database/sql/#NullString
特别是使用 sql 空类型,其中存在 "no valid value for this field" 的概念是有意义的。
我正在通过使用 Gqlgen 和 Gorm(postgres 方言)开发一个用 Go 编写的 Web 服务器来练习。
我首先描述了我的用户模型:
# dbm.User{}
type User struct {
BaseModel
Email string `gorm:"not null;unique_index:idx_email"`
UserID *string // External user ID
Name *string
NickName *string
FirstName *string
LastName *string
Location *string `gorm:"size:1048"`
Description *string `gorm:"size:1048"`
}
在这种情况下,据我所知,在我的结构中为某些值使用指针是很好的,因为当没有附加值时它们可以评估为 <nil>
。而如果我不使用指针,如果没有附加任何值,则 int 将为 0。好吧,这是有道理的……如果我没记错的话……
但是,我现在面临的困难是从数据库上的 Gorm 操作中获取此值时:
dbRecord := &dbm.User{}
db = db.Where(whereEmail, email).Find(&dbRecord)
fmt.Println("dbRecord:", dbRecord)
// Prints:
// dbRecord: &{{def90b3c-93ff-40f0-8d33-6320dddbe3f2 2019-10-01 14:16:34.365395 +0200 CEST 2019-10-01 14:16:34.365395 +0200 CEST} test@test.com <nil> 0xc0000a1cb0 0xc0000a1cd0 0xc0000a1cc0 <nil> 0xc0000a1cf0 0xc0000a1ce0}
这段代码查询了一个用户,其中email是"email@email.com",显然结构中的一些字段指向了值的实际地址。这是有道理的,但是如果我要读取这些数据就很烦人了。有读取这些数据的常规方法吗?
我尝试的是将此结构转换为 GQL 结构(由 GQLgen 自动生成):
# gqlm.User{}
type User struct {
ID string `json:"id"`
Email string `json:"email"`
UserID *string `json:"userId"`
Name *string `json:"name"`
FirstName *string `json:"firstName"`
LastName *string `json:"lastName"`
NickName *string `json:"nickName"`
Description *string `json:"description"`
Location *string `json:"location"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt *time.Time `json:"updatedAt"`
}
但是,当我需要值时,我又得到了地址,这是有道理的。
所以我找到的唯一方法是创建一个新的自定义结构 customUser,编组来自 Gorm 的数据,然后将其解组到我的 customUser 结构中:
type customUser struct {
ID string `json:"id"`
Email string `json:"email"`
UserID string `json:"userId"`
Name string `json:"name"`
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
NickName string `json:"nickName"`
Description string `json:"description"`
Location string `json:"location"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
bs, _ := json.Marshal(record)
var s = string(bs)
newRecord := &customUser{}
bs = []byte(s) // This is maybe not necessary
err = json.Unmarshal(bs, newRecord)
if err != nil {
fmt.Println(err)
}
fmt.Printf("record: %+v\n", newRecord)
// I now get the right format: record: &{ID:def90b3c-93ff-40f0-8d33-6320dddbe3f2 Email:test@test.com UserID: Name:frer FirstName:fwef LastName: NickName:trgt Description:werfergh rthrt hr Location:wfwf CreatedAt:2019-10-01 14:16:34.365395 +0200 CEST UpdatedAt:2019-10-01 14:16:34.365395 +0200 CEST}
但这似乎太过分了,如果我每次需要从数据库读取数据时都需要创建这样的结构,那么需要付出很多努力。这是要走的路吗?或者你知道更方便的方法吗?
您需要对字符串指针类型使用 sql.NullString。
请参阅https://golang.org/pkg/database/sql/#NullString
特别是使用 sql 空类型,其中存在 "no valid value for this field" 的概念是有意义的。