我使用 database/sql 并定义了一个到 DB 表列(标签字段)的结构映射:
// Users ...
type Users struct {
ID int64 `field:"id"`
Username string `field:"username"`
Password string `field:"password"`
Tel string `field:"tel"`
}
Run Code Online (Sandbox Code Playgroud)
然后我查询:
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)
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的rows.Scan(),我必须编写所有列,而且我认为这不是 20 列或更多列的好方法。
如何以清晰的方式扫描。
Rif*_*ife 13
使用反射是一个很好的做法:
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)
}
Run Code Online (Sandbox Code Playgroud)
您可以考虑使用 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
}
Run Code Online (Sandbox Code Playgroud)