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

我正在尝试将 SQL 查询数据集存储在结构中并以 JSON 显示。我几乎做到了。现在的问题是,如果嵌套结构的结果集为空,那么我不想显示它。


此处指定了相同的问题,但在扫描时使用指针以恐慌结束可能是因为我正在使用&user.Profile.Firstname


2015/11/01 16:42:16 恐慌恢复-> 运行时错误:无效的内存地址或空指针取消引用


如果我删除指针,那么一切正常,只剩下空字段。我很困惑如何实现这一目标。


package main


import (

    "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.DB


func 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": {

  }

},


12345678_0001
浏览 165回答 1
1回答

慕沐林林

假设在幕后gin使用encoding/json,如果你想省略一个空的Profile,我相信你需要它是一个指针User:type User struct {    ....    Profile *Profile `json:",omitempty"`}请注意文档:“omitempty”选项指定如果字段具有空值(定义为 false、0、nil 指针、nil 接口值以及任何空数组、切片、映射或字符串),则应从编码中省略该字段。它并不是说将检测到结构体的零值。这会给您从数据库扫描数据时遇到一些问题。您可以声明 a Profile,扫描到其中,与零配置文件进行比较并将其分配给 ,User如果它有数据:var user Uservar profile Profile_ = stmt.Scan(&user.Id, &user.Username, &user.Email, &profile.Firstname, &profile.Lastname)if profile != Profile{} {    user.Profile = &profile}我怀疑这不是最优雅的解决方案,但我希望这是正确的方向。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go