You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang Fiber框架返回数据库查询结果JSON数组为空问题求助

问题修复方案

核心错误原因

Go 语言的 JSON 序列化规则要求:只有首字母大写的公有字段才能被序列化库读取输出。你定义的 sessionsInfo 结构体所有字段都是小写开头的包私有字段,序列化时无法被识别,因此返回的每个对象都是空的。你控制台能正常打印内容,是因为fmt包可以访问同包下的私有字段,和JSON序列化的权限规则不同,数组长度和数据条数匹配是因为你正确插入了对应数量的结构体元素到数组中。

其他隐藏问题

  • defer rows.Close() 放置位置错误,应该在拿到 rows 且确认无查询错误后立即声明,否则如果 db.Query 执行失败返回空 rows,后续执行关闭操作会触发空指针 panic
  • 没有捕获 rows.Scan 的返回错误,会漏掉数据读取异常的场景
  • 调用 c.JSON() 后重复调用 c.SendStatus(200) 属于冗余操作,c.JSON 方法默认已经返回 200 状态码,重复调用可能导致响应异常

修复后代码

// 结构体字段首字母大写,同时加json标签指定序列化后输出的字段名
type sessionsInfo struct {
    Token     string `json:"token"`
    UserId    int    `json:"user_id"`
    LastSeen  string `json:"last_seen"`
}

app.Get("/testA", func(c *fiber.Ctx) error {
    logMsg("GET /testA")
    execQuery := `select * from sessions`
    rows, err := db.Query(execQuery)
    if err != nil {
        fmt.Println(err)
        return c.SendStatus(418)
    }
    // 获取到rows后立即defer关闭
    defer rows.Close()

    var sessionsArray []sessionsInfo
    for rows.Next(){
        var sessions sessionsInfo
        // 捕获Scan的错误
        err := rows.Scan(
            &sessions.Token,
            &sessions.UserId,
            &sessions.LastSeen,
        )
        if err != nil {
            fmt.Println(err)
            return c.SendStatus(500)
        }
        sessionsArray = append(sessionsArray, sessions)
    }

    // 检查遍历rows的整体错误
    if err = rows.Err(); err != nil {
        fmt.Println(err)
        return c.SendStatus(500)
    }

    fmt.Println(sessionsArray)
    // c.JSON默认返回200状态码,不需要额外调用SendStatus
    return c.JSON(sessionsArray)
})

内容的提问来源于stack exchange,提问作者Andy Renderhauer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 23:00:01