Golang:在嵌套结构存储SQL结果集和省略,如果空

问题描述:

我试图存储SQL查询的数据集在一个JSON结构和显示。我已经差不多完成了。现在的问题是嵌套结构的结果集是空的,我不想显示它。Golang:在嵌套结构存储SQL结果集和省略,如果空

同样的问题specified here但使用指针在恐慌扫描,因为我使用&user.Profile.Firstname

2015/11/01 16:42:16 Panic recovery -> runtime error: invalid memory address or nil pointer dereference

可能是当如果我删除的指针则一切正常只是空场仍然结束。我很困惑如何实现这一点。

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:[email protected]/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": "[email protected]", 
    "Profile": { 
    "Firstname": "John", 
    "Lastname": "Doe" 
    } 
}, 
{ 
    "Id": 2, 
    "Username": "test2", 
    "Email": "[email protected]", 
    "Profile": { 
    } 
}, 

假设gin使用encoding/json被窝里,如果你想省略空Profile,我相信你需要它是在User指针:

type User struct { 
    .... 
    Profile *Profile `json:",omitempty"` 
} 

注意documentation

The "omitempty" option specifies that the field should be omitted from the encoding if the field has an empty value, defined as false, 0, a nil pointer, a nil interface value, and any empty array, slice, map, or string.

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

,将让你的一些问题从DB扫描您的数据。你可以声明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 
} 

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