如何使用行扫描Go的数据库/ SQL

时间:2019-06-10 11:26:01

标签: go

我使用数据库/ sql并定义到数据库表列(标记字段)的结构映射:

// Users ...
type Users struct {
    ID            int64  `field:"id"`                      
    Username      string `field:"username"`           
    Password      string `field:"password"`           
    Tel           string `field:"tel"`                   
}

然后我查询:

        rows, err := db.Query(sql)  // select * from users
        if err != nil {
            fmt.Println(err)
        }
        defer rows.Close()
        for rows.Next() {
            user := new(Users)

            // works but I don't think it is good code for too many columns
            err = rows.Scan(&user.ID, &user.Username, &user.Password, &user.Tel)

            // TODO: How to scan in a simple way 


            if err != nil {
                fmt.Println(err)
            }
            fmt.Println("user: ", user)
            list = append(list, *user)
        }
        if err := rows.Err(); err != nil {
            fmt.Println(err)
        }

您可以看到rows.Scan()的所有列,我认为这不是20列或更多列的好方法。

如何进行清晰的扫描。

2 个答案:

答案 0 :(得分:1)

您可以考虑使用jmoiron的sqlx软件包。它支持分配给结构。

自述文件的摘录:

type Place struct {
    Country string
    City    sql.NullString
    TelCode int
}
 places := []Place{}
 err = db.Select(&places, "SELECT * FROM place ORDER BY telcode ASC")
 if err != nil {
     fmt.Println(err)
      return
 }

答案 1 :(得分:0)

使用反射是一个好习惯:

    for rows.Next() {
        user := Users{}

        s := reflect.ValueOf(&user).Elem()
        numCols := s.NumField()
        columns := make([]interface{}, numCols)
        for i := 0; i < numCols; i++ {
            field := s.Field(i)
            columns[i] = field.Addr().Interface()
        }

        err := rows.Scan(columns...)
        if err != nil {
            log.Fatal(err)
        }
        log.Println(user)
    }