首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在GO Golang中提取SQL结果集的更简洁的函数

在GO Golang中提取SQL结果集的更简洁的函数
EN

Stack Overflow用户
提问于 2022-04-10 13:16:05
回答 1查看 258关注 0票数 0

我想从MySQL数据库中检索一个应用程序I数组。我使用了http://go-database-sql.org的示例代码:

代码语言:javascript
复制
func QueryAppList() *[]int64 {
    var (
        appList []int64
        appid   int64
    )
    qry := "SELECT a.appid FROM app a WHERE a.app_status IN (1, 2);"
    // cfg.GetDb() supplies the database connection already established
    rows, err := cfg.GetDb().Query(qry) 
    if err != nil {
        logg.Error(err)
        return &appList
    }
    defer func(rows *sql.Rows) { 
        // simple defer does not catch every error: https://www.joeshaw.org/dont-defer-close-on-writable-files/
        err := rows.Close()
        if err != nil {
            logg.Error(err)
        }
    }(rows)
    for rows.Next() {
        err := rows.Scan(&appid)
        if err != nil {
            logg.Error(err)
            return &appList
        }
        appidList = append(appList, appid)
    }
    err = rows.Err()
    if err != nil {
        logg.Error(err)
        return &appList
    }
    return &appidList
}

我的程序中会有这样的查询。获取结果列表的所有方法以及如何防止失败,使得这个小查询很难理解实际发生了什么。

有办法使查询更简洁吗?

以下是我的想法,以减少代码的冗长性:

  • 使用函数来处理错误,将错误处理减少到一行。如果是一个列数组,则
  • 可以将查询和列名作为参数传递,并重用查询函数。我宁愿重写一个查询函数,也不愿处理复杂的abstractions.
  • Are包--我错过了帮助减少杂乱的

的包。

使用像gorm这样的ORM不是一种选择。

我刚开始进行Go编程,所以我缺乏语言方面的经验。

下面是Node.js中具有相同结果的相同查询。它有9行,而围棋的34,即65%,更简洁的长度。这是我理想中想去的地方。

代码语言:javascript
复制
import {query} from "../db/pool"; // connection pool query from https://github.com/sidorares/node-mysql2

export const queryAppList = async () => {
  try {
    const qry = "SELECT a.appid FROM app a WHERE a.app_status IN (1, 2);";
    const [appList] = await query(qry);
    return appList; 
  } catch (err) {
    console.error(err)
    return [];
  }
};
EN

回答 1

Stack Overflow用户

发布于 2022-04-10 14:18:14

您可以创建一个具有可重用方法的查询结构。

就像这样:

代码语言:javascript
复制
type Query struct{
    conn *sql.DB
    rows *sql.Rows
    ...
}

func NewQuery(conn *sql.DB) *Query {
    return &Query{
        conn: conn,
        rows: nil,
    }
}

func (q Query) OpenSQL(sql string) error {
    q.rows, err = q.conn.Query(sql)
    if err != nil {
        log.Error("SQL error during query ("+sql+"). "+err.Error())
        return err
    }
    return nil
}

func (q Query)Close() (error) {
    err := q.rows.Close()
    if err != nil {
        log.Error("Error closing rows. "+err.Error())
        return err
    }
    return nil
}

//You can use generic functions to make the code even smaller
func FetchToSlice[T any](q Query) ([]T, error) {
    result := make([]T, 0)
    var value T
    for q.rows.Next() {
        err := q.rows.Scan(&value)
        if err != nil {
           log.Error("Error during fetching. "+err.Error())
           return nil, err
        }
        result = append(result, value)
    }
    return result, nil
} 

有了这个代码,您的代码将如下所示:

代码语言:javascript
复制
qry := NewQuery(cfg.GetDB())
err := qry.OpenSQL("SELECT a.appid FROM app a WHERE a.app_status IN (1, 2);")
if err != nil {
    return err
}
defer qry.Close()
appidList, err := FetchToSlice[int](qry)
if err != nil {
    return err
}

以后,可以向查询中添加更多方法以处理更复杂的情况,甚至可以使用sync.Pool缓存查询结构等等。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71816948

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档