Scan方法支持将查询结果转换为结构体或者结构体数组,Scan方法将会根据给定的参数类型自动识别执行的转换类型。

struct对象

Scan支持将查询结果转换为一个struct对象,查询结果应当是特定的一条记录,并且pointer参数应当为struct对象的指针地址(*struct或者**struct),使用方式例如:

type User struct {
    Id         int
    Passport   string
    Password   string
    NickName   string
    CreateTime *gtime.Time
}
user := User{}
g.Model("user").Where("id", 1).Scan(&user)

或者

var user = User{}
g.Model("user").Where("id", 1).Scan(&user)

前两种方式都是预先初始化对象(提前分配内存),推荐的方式:

var user *User
g.Model("user").Where("id", 1).Scan(&user)

这种方式只有在查询到数据的时候才会执行初始化及内存分配。注意在用法上的区别,特别是传递参数类型的差别(前两种方式传递的参数类型是*User,这里传递的参数类型其实是**User)。

struct数组

Scan支持将多条查询结果集转换为一个[]struct/[]*struct数组,查询结果应当是多条记录组成的结果集,并且pointer应当为数组的指针地址,使用方式例如:

var users []User
g.Model("user").Scan(&users)

或者

var users []*User
g.Model("user").Scan(&users)






















Content Menu

  • No labels

15 Comments

  1. 可不可以增加一个参数或者是函数来让Scan方法自动初始化切片?

    例如:

    type Response struct {
    	Users []User `json:"users"`
    }
    
    type User struct {
    	Id       uint   `json:"id"`
    	Username string `json:"username"`
    	Name     string `json:"name"`
    }
    
    var resp Response
    dao.XXX.Ctx(ctx).AutoMakeSlice(0, 0).Scan(&resp.Users) // AutoMakeSlice的两个参数对应make函数的第二、第三参数
    
    g.Dump(resp)
    // output:
    // {
    //   "users": []
    // }


    1. 当没有数据的时候不会自动初始化的,若有问题请提issue

      1. 切片\数组不初始化的话转换json后是null而不是空数组

      2. 我也想,没有数据的时间进行初始化,不然每次返回前端默认数组是null

        1. 先make再scan

          var list = make([]*assembly.TenantInventoryPsi, 0)
          err := g.Model("xxx").Scan(&list)
  2. ScanAndCount这个方法好鸡肋。直接Scan出来再len()求一下就有Count了,还少一次IO。

    还不如把它设计成ScanAdnCount( & rs, & total, offset, limit) 这样还实用些。先求没有offset及limit限制的Count,再加上offset及limit后进行scan

    1. 并不是len一下就有Count,这个是给分页用的,返回的是总数的Count

      1. 它会忽略 Offset及Limit设置?

        1. 查询Count的时候会忽略的。已增加相关文档:

          1. 之前一直以为Count会被limit约束。才知道原来不会。

  3. 话说Scan中指针和不用指针的结果是一样的吗?

    比如

    type Lisi struct { User *User }

    type Lisi struct { User User }

    扫描出来的结果是一样的吗?

  4. Scan 的err抛出 no rows in result set 怎么解决,我认为这不是一个错误

    1. 这个错误是sql包定义的,如果要屏蔽这个错误可以对dao做一次封装判定一次 if err == sql.ErrNoRows { return nil}

  5. 请问下匿名结构体中的字段查不到值这个有办法处理吗

    数据库是有值的,使用with方式能查出来


  6. 请问一下同一函数内,scan执行两遍,会查询两遍数据库吗?