go - 多次循环通过数据库/ sql sql.Rows?
问题描述
我需要循环返回sql.Rows
多次。我只有两个选择:
- 将返回的结果缓存在本地数据结构中;
- 重做数据库查询?
换句话说,没有办法返回sql.Rows
(即与 相反Rows.Next
)。
解决方案
另一种解决方案是使用装饰器模式:
// A RowsDecorator wraps sql.Rows and allows a callback to be called whenever Scan is called
type RowsDecorator struct {
*sql.Rows
OnScan func([]interface{}, error)
}
func Wrap(rows *sql.Rows, onScan func([]interface{}, error)) *RowsDecorator {
return &RowsDecorator{Rows: rows, OnScan: onScan}
}
// Scan calls Rows.Scan and an optional callback
func (rows *RowsDecorator) Scan(dest ...interface{}) error {
err := rows.Rows.Scan(dest...)
if rows.OnScan != nil {
rows.OnScan(dest, err)
}
return err
}
像这样使用:
db.Exec(`CREATE TABLE example (id INTEGER, txt TEXT)`)
db.Exec(`INSERT INTO example (id, txt) VALUES (1, 'test-1'), (2, 'test-2'), (3, 'test-3') `)
rawrows, err := db.Query("SELECT id, txt FROM example")
if err != nil {
log.Fatal(err)
}
defer rawrows.Close()
sum := 0
rows := Wrap(rawrows, func(dest []interface{}, err error) {
if err == nil {
sum += *dest[0].(*int)
}
})
for rows.Next() {
var id int
var txt string
err := rows.Scan(&id, &txt)
if err != nil {
log.Fatal(err)
}
log.Println(id, txt)
}
log.Println("sum", sum)
使用这种模式,您可以编写一个自定义函数,在您遍历集合时调用该函数。通过使用未命名的嵌入类型,仍然可以调用所有原始方法(Next、Close 等)。
推荐阅读
- snowflake-cloud-data-platform - 如果持续约 5 分钟,对 Snowflake 的 DBeaver 查询会导致“SQL 错误 [604] [57014]:SQL 执行已取消”
- swift - Swift:从 firebase 获取 1500 多张图片。请给我建议专业的方法
- javascript - 迁移到角度 9 后,无法在 colorPickerComponent 处读取未定义的属性“nativeElement”
- mapbox-gl-js - 变焦时俯仰相机
- node.js - EventEmitter 类型上不存在观察到的属性
- ethernet - 如何通过以太网将树莓派连接到 Rs logix 仿真器 500
- intellij-idea - IntelliJ IDE错误java:发现警告并指定-Werror
- vuejs2 - 尽管 URL 已更改,但无法加载组件
- realex-payments-api - iOS 和 Android 上的 3DS2:HPP 还是 API?
- java - 为第三方 jar 应用设置深色背景