Golang中如何存储MySQL查询结果集

Golang中如何存储MySQL查询结果集 如何将MySQL数据存储在结果集中以供后续使用。

示例:我将查询一个表并将结果存储在结果集中。无论何时需要,我都可以使用相同的结果集。

4 回复

这对你来说真的是个问题吗?复制操作并没有那么慢。你测量过吗?

更多关于Golang中如何存储MySQL查询结果集的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


谢谢。

我理解你的方法,但将相同的数据复制到映射或数组中并不是一个好主意(扫描和复制会花费时间)。我们能否将其保留在内存地址中,并且能否多次使用它?

我不太确定这个问题,但无论如何我会尝试回答一下 😊

我的做法是将结果集中的所有数据读取到我自定义的数据结构中。这可以是一个映射(map)或者一个结构体(struct)数组。具体取决于你在查询中获取的数据类型。在映射完成后,我会使用 Close() 函数关闭结果集,然后操作我自己的数据副本。

func main() {
    fmt.Println("hello world")
}

在Golang中处理MySQL查询结果集,通常使用database/sql包配合MySQL驱动(如github.com/go-sql-driver/mysql)。查询结果不会直接存储在类似其他语言中的“结果集”对象里,而是通过迭代Rows或使用结构体映射来存储数据。

以下是几种常见方法:

1. 使用sql.Rows迭代访问

这是最基础的方式,适合动态或未知结构的查询:

rows, err := db.Query("SELECT id, name FROM users WHERE age > ?", 18)
if err != nil {
    log.Fatal(err)
}
defer rows.Close()

var results []map[string]interface{}
for rows.Next() {
    var id int
    var name string
    if err := rows.Scan(&id, &name); err != nil {
        log.Fatal(err)
    }
    results = append(results, map[string]interface{}{
        "id":   id,
        "name": name,
    })
}
// 后续可通过results变量重复使用数据

2. 映射到结构体切片(推荐)

定义与表结构对应的Go结构体,使用切片存储结果:

type User struct {
    ID   int    `db:"id"`
    Name string `db:"name"`
    Age  int    `db:"age"`
}

func getUsers() ([]User, error) {
    rows, err := db.Query("SELECT id, name, age FROM users")
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    var users []User
    for rows.Next() {
        var u User
        if err := rows.Scan(&u.ID, &u.Name, &u.Age); err != nil {
            return nil, err
        }
        users = append(users, u)
    }
    return users, nil
}

// 调用示例
userList, err := getUsers()
if err != nil {
    log.Fatal(err)
}
// userList 包含所有查询结果,可重复使用

3. 使用第三方库(如sqlx)

sqlx库简化了结构体映射过程:

import "github.com/jmoiron/sqlx"

type Product struct {
    ID    int     `db:"id"`
    Name  string  `db:"name"`
    Price float64 `db:"price"`
}

var products []Product
err := sqlx.DB.Select(&products, "SELECT * FROM products")
if err != nil {
    log.Fatal(err)
}
// products切片已包含所有结果

4. 缓存单行查询结果

对于单行查询,可直接存储到变量或结构体:

var totalCount int
row := db.QueryRow("SELECT COUNT(*) FROM orders")
err := row.Scan(&totalCount)
if err != nil {
    log.Fatal(err)
}
// totalCount变量存储了查询结果

完整示例(标准库版本)

package main

import (
    "database/sql"
    "log"
    _ "github.com/go-sql-driver/mysql"
)

func main() {
    db, err := sql.Open("mysql", "user:pass@tcp(127.0.0.1:3306)/dbname")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // 执行查询并存储结果
    rows, err := db.Query("SELECT id, username FROM users")
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    // 定义存储结构
    type Result struct {
        ID       int
        Username string
    }
    
    var results []Result
    for rows.Next() {
        var r Result
        if err := rows.Scan(&r.ID, &r.Username); err != nil {
            log.Fatal(err)
        }
        results = append(results, r)
    }

    // 检查迭代错误
    if err := rows.Err(); err != nil {
        log.Fatal(err)
    }

    // 现在results切片包含所有查询数据,可随时使用
    for _, res := range results {
        log.Printf("ID: %d, Username: %s", res.ID, res.Username)
    }
}

关键点:

  • 使用db.Query()获取sql.Rows对象
  • 通过rows.Next()迭代所有行
  • 使用rows.Scan()将每行数据读取到变量
  • 将数据存储到切片中实现重复使用
  • 单次查询后rows会关闭,必须将数据保存到变量中才能后续使用

这样存储的结果集数据可以像普通Go数据结构一样反复访问,无需重新查询数据库。

回到顶部