猿问

在同一个函数中对 Postgres 的多个查询

我是 Go 的新手,很抱歉提前提出这个愚蠢的问题!


我正在使用 Gin 框架并希望在同一个处理程序 ( database/sql+ lib/pq)中对数据库进行多个查询


userIds := []int{}

bookIds := []int{}

var id int


/* Handling first query here */

rows, err := pgClient.Query(getUserIdsQuery)

defer rows.Close()

if err != nil {

    return

}

for rows.Next() {

    err := rows.Scan(&id)

    if err != nil {

        return

    }

    userIds = append(userIds, id)

}


/* Handling second query here */

rows, err = pgClient.Query(getBookIdsQuery)

defer rows.Close()

if err != nil {

    return

}

for rows.Next() {

    err := rows.Scan(&id)

    if err != nil {

        return

    }

    bookIds = append(bookIds, id)

}

我有几个关于此代码的问题(任何改进和最佳实践将不胜感激)

  1. defer rows.Close()在这种情况下,Go 能正确处理吗?我的意思是我rows稍后会在代码中重新分配变量,所以编译器会跟踪这两个变量并在函数结束时正确关闭吗?

  2. 可以重用id共享变量还是应该在循环内迭代时重新声明它rows.Next()

  3. 在一个处理程序中进行更多查询的更好方法是什么?我应该有某种Writer接受查询和切片并用检索到的 ID 填充它的东西吗?

谢谢。


ABOUTYOU
浏览 98回答 1
1回答

慕容708150

我从未与go-pg图书馆合作过,我的回答主要集中在其他通用的东西上,并不特定于 golang 或 go-pg。不管rowshere 在两个查询之间共享时具有相同的引用(所以一个rows.Close()调用就足够了,除非库有一些特殊的实现),定义两个变量更清晰,比如userRows和bookRows。虽然我已经说过我没有使用过go-pg,但我相信您不需要遍历行并手动扫描所有行的 id,我相信 lib 已经提供了一些这样的 API(基于对文档):userIds := []int{}err := pgClient.Query(&userIds, "select id from users where ...", args...)关于你的第二个问题,这取决于你所说的“好的”是什么意思。由于您进行了一些同步迭代,我认为这不会导致错误,但就编码风格而言,就个人而言,我不会这样做。我认为在你的情况下最好的做法是:// repo layerfunc getUserIds(args whatever) ([]int, err) {...}// these can be exposed, based on your packaging logicfunc getBookIds(args whatever) ([]int, err) {...}// service layer, or wherever you want to aggregate both queriesfunc getUserAndBookIds() ([]int, []int, err) {    userIds, err := getUserIds(...)    // potential error handling    bookIds, err := getBookIds(...)    // potential error handling    return userIds, bookIds, nil // you have done err handling earlier}我认为这段代码更容易阅读/维护。您不会面临变量重新分配和其他问题。您可以查看go-pg 文档,了解有关如何改进查询的更多详细信息。
随时随地看视频慕课网APP

相关分类

Go
我要回答