通常我会写这样的东西
rows := db.MyPgConn.QueryRows(`SELECT * FROM bla`) // or any other query
for rows.Next() { // if there are result
// rows.Scan(
// do custom operation
}
rows.Close() // close recordset
但是这样,有可能我忘记编写rows.Close()
,就像这个code那样可以使可用连接/套接字的数量耗尽,有更好的方法吗?
答案 0 :(得分:4)
为此目的完全引入defer
。
rows := db.MyPgConn.QueryRows(`SELECT * FROM bla`) // or any other query
defer rows.Close()
for rows.Next() { // if there are result
// rows.Scan(
// do custom operation
}
来自文档:
推迟对
Close
等函数的调用有两个好处。首先,它保证您永远不会忘记关闭文件,如果您稍后编辑函数以添加新的返回路径,则很容易犯这个错误。其次,这意味着关闭位于开放附近,这比将其放置在功能的末尾要清晰得多。
答案 1 :(得分:1)
正如Intermernet所提到的,defer语句是使close语句更接近于声明rows var的最佳方法。我能想到的唯一方法可能是缩短或更简单,就是在数据库调用周围创建一个包装函数。
func performQuery(q string, op func(db.rows)) {
rows := db.MyPg.Conn.QueryRows(q)
// defer rows.Close()
op(rows)
rows.Close()
}
// then we could do:
performQuery(`SELECT * FROM bla`,func(rows db.Rows) {
for rows.Next() {
// rows.Scan(
}
})
然而,这会限制您使用参数进行查询(例如SELECT * FROM tableName WHERE id = $1
。