[已解决]Golang如何从数据库读取所有行数据并存入结构体数组

[已解决]Golang如何从数据库读取所有行数据并存入结构体数组 我编写了这段代码来从用户表中读取所有行:

func GetAllUsers(db *sql.DB, w http.ResponseWriter, r *http.Request) {

	ctx := context.Background()
	users := make([]model.User, 0)

	rows, err := db.QueryContext(ctx, "select * from users")

	if err != nil {
		panic(err)
	}

	fmt.Println(rows)

	for rows.Next() {
		var user model.User

		if err := rows.Scan(&user); err != nil {
			log.Fatal(err)
		}
		users = append(users, user)
	}

	respondJSON(w, http.StatusOK, users)
}

但是遇到了这个错误:

sql: 转换参数 $1 类型时出错:不支持的类型 model.User,这是一个结构体切片

请帮我修复这个问题。


更多关于[已解决]Golang如何从数据库读取所有行数据并存入结构体数组的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

在大家的帮助下,我找到了问题所在:

func GetAllUsers(db *sql.DB, w http.ResponseWriter, r *http.Request) {

	ctx := context.Background()
	

	rows, err := db.QueryContext(ctx, "select * from users")

	if err != nil {
		panic(err)
	}

        users := make([]model.User, 0)
	for rows.Next() {
		var user model.User
		if err := rows.Scan(&user.Name, &user.Avatar, &user.Mobile, &user.BirthDay, &user.Identify, &user.Cart, &user.Credit, &user.Password, &user.Type, &user.Email, &user.Id); err != nil {
			log.Fatal(err)
		}

		users = append(users, user)
	}


	respondJSON(w, http.StatusOK, users)
}

希望这对其他人有所帮助。

更多关于[已解决]Golang如何从数据库读取所有行数据并存入结构体数组的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你的代码问题在于 rows.Scan(&user) 试图将整个结构体作为单个参数扫描,但 Scan() 需要的是与查询列对应的独立字段指针。以下是修复后的代码:

func GetAllUsers(db *sql.DB, w http.ResponseWriter, r *http.Request) {
    ctx := context.Background()
    users := make([]model.User, 0)

    rows, err := db.QueryContext(ctx, "SELECT id, name, email, created_at FROM users")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    defer rows.Close()

    for rows.Next() {
        var user model.User
        // 根据User结构体的实际字段进行扫描
        err := rows.Scan(&user.ID, &user.Name, &user.Email, &user.CreatedAt)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        users = append(users, user)
    }

    // 检查迭代过程中是否出错
    if err = rows.Err(); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    respondJSON(w, http.StatusOK, users)
}

如果你的 model.User 结构体定义如下:

package model

import "time"

type User struct {
    ID        int       `json:"id"`
    Name      string    `json:"name"`
    Email     string    `json:"email"`
    CreatedAt time.Time `json:"created_at"`
}

对于更简洁的写法,可以使用 sqlx 库:

import "github.com/jmoiron/sqlx"

func GetAllUsersSQLX(db *sqlx.DB, w http.ResponseWriter, r *http.Request) {
    users := []model.User{}
    
    err := db.Select(&users, "SELECT * FROM users")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    
    respondJSON(w, http.StatusOK, users)
}

关键点:

  1. rows.Scan() 需要传入与查询列顺序匹配的每个字段的指针
  2. 使用 defer rows.Close() 确保资源释放
  3. 检查 rows.Err() 处理迭代过程中的错误
  4. 避免在生产环境中使用 panic()log.Fatal()
回到顶部