为了账号安全,请及时绑定邮箱和手机立即绑定

将 Sql 结果集存储在嵌套结构中,如果为空则省略

将 Sql 结果集存储在嵌套结构中,如果为空则省略

Go
12345678_0001 2021-11-22 10:28:48
我正在尝试将 SQL 查询数据集存储在结构中并以 JSON 显示。我几乎做到了。现在的问题是,如果嵌套结构的结果集为空,那么我不想显示它。此处指定了相同的问题,但在扫描时使用指针以恐慌结束可能是因为我正在使用&user.Profile.Firstname2015/11/01 16:42:16 恐慌恢复-> 运行时错误:无效的内存地址或空指针取消引用如果我删除指针,那么一切正常,只剩下空字段。我很困惑如何实现这一目标。package mainimport (    "database/sql"    "github.com/gin-gonic/gin"    _ "github.com/go-sql-driver/mysql"    "log")type User struct {    Id       int64    Username string    Email    string    Profile  Profile `json:",omitempty"`}type Profile struct {    Id        int64  `json:",omitempty"`    UserId    int64  `json:",omitempty"`    Firstname *string `json:",omitempty"`    Lastname  *string `json:",omitempty"`}var DB *sql.DBfunc checkErr(err error, msg string) {    if err != nil {        log.Fatal(msg, err)    }}func main() {    DB, _ = sql.Open("mysql", "username:secrect@/database")    defer DB.Close()    r := gin.Default()    v1 := r.Group("api/v1/")    {        v1.GET("users", GetUsers)    }    r.Run(":8080")}func GetUsers(c *gin.Context) {    stmt, err := DB.Query("Select users.id, username , email , firstname , lastname from users left join profiles on users.id = profiles.user_id ")    if err != nil {        panic(err.Error())    }    defer stmt.Close()    users := []User{}    for stmt.Next() {        var user User        err := stmt.Scan(&user.Id, &user.Username, &user.Email, &user.Profile.Firstname, &user.Profile.Lastname)        if err != nil {            panic(err.Error())        }        users = append(users, user)    }    c.JSON(200, &users)}输出:{  "Id": 1,  "Username": "test1",  "Email": "test1@example.com",  "Profile": {    "Firstname": "John",    "Lastname": "Doe"  }},{  "Id": 2,  "Username": "test2",  "Email": "test2@example.com",  "Profile": {  }},
查看完整描述

1 回答

?
慕沐林林

TA贡献2016条经验 获得超9个赞

假设在幕后gin使用encoding/json,如果你想省略一个空的Profile,我相信你需要它是一个指针User:


type User struct {

    ....

    Profile *Profile `json:",omitempty"`

}

请注意文档:


“omitempty”选项指定如果字段具有空值(定义为 false、0、nil 指针、nil 接口值以及任何空数组、切片、映射或字符串),则应从编码中省略该字段。


它并不是说将检测到结构体的零值。


这会给您从数据库扫描数据时遇到一些问题。您可以声明 a Profile,扫描到其中,与零配置文件进行比较并将其分配给 ,User如果它有数据:


var user User

var profile Profile

_ = stmt.Scan(&user.Id, &user.Username, &user.Email, &profile.Firstname, &profile.Lastname)

if profile != Profile{} {

    user.Profile = &profile

}

我怀疑这不是最优雅的解决方案,但我希望这是正确的方向。


查看完整回答
反对 回复 2021-11-22
  • 1 回答
  • 0 关注
  • 155 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信