痛点描述

经过前面的章节介绍,如果给定一个未初始化的数组(值为 nil),在 ORM 根据给定条件未查询到数据时,并不会自动初始化该数组。因此该未初始化的数组结果如果通过 JSON 进行编码后,会被转换为 null 值。

  1. package main
  2. import (
  3. _ "github.com/gogf/gf/contrib/drivers/mysql/v2"
  4. "fmt"
  5. "github.com/gogf/gf/v2/encoding/gjson"
  6. "github.com/gogf/gf/v2/frame/g"
  7. "github.com/gogf/gf/v2/os/gtime"
  8. )
  9. func main() {
  10. type User struct {
  11. Id uint64 // 主键
  12. Passport string // 账号
  13. Password string // 密码
  14. NickName string // 昵称
  15. CreatedAt *gtime.Time // 创建时间
  16. UpdatedAt *gtime.Time // 更新时间
  17. }
  18. type Response struct {
  19. Users []User
  20. }
  21. var res = &Response{}
  22. err := g.Model("user").WhereGT("id", 10).Scan(&res.Users)
  23. fmt.Println(err)
  24. fmt.Println(gjson.MustEncodeString(res))
  25. }

执行后,终端展示结果为:

  1. <nil>
  2. {"Users":null}

在大部分场景下, ORM 查询的数据需要渲染展示在浏览器页面上,也就意味着返回的数据需要给前端 JS 进行处理。为了对前端 JS 处理后端返回数据时更加友好,如果在后端查询不到数据时,期望返回一个空的数组结构,而不是返回一个 null 属性值。

改进方案

针对这种场景,可以给 ORMScan 方法一个初始化的空数组即可。当 ORM 查询不到数据时,该数组属性仍然是一个空数组,而不是 nil,返回 JSON 编码后也不会是 null 值。

  1. package main
  2. import (
  3. _ "github.com/gogf/gf/contrib/drivers/mysql/v2"
  4. "fmt"
  5. "github.com/gogf/gf/v2/encoding/gjson"
  6. "github.com/gogf/gf/v2/frame/g"
  7. "github.com/gogf/gf/v2/os/gtime"
  8. )
  9. func main() {
  10. type User struct {
  11. Id uint64 // 主键
  12. Passport string // 账号
  13. Password string // 密码
  14. NickName string // 昵称
  15. CreatedAt *gtime.Time // 创建时间
  16. UpdatedAt *gtime.Time // 更新时间
  17. }
  18. type Response struct {
  19. Users []User
  20. }
  21. var res = &Response{
  22. Users: make([]User, 0),
  23. }
  24. err := g.Model("user").WhereGT("id", 10).Scan(&res.Users)
  25. fmt.Println(err)
  26. fmt.Println(gjson.MustEncodeString(res))
  27. }

执行后,终端展示结果为:

  1. <nil>
  2. {"Users":[]}