为了更好地学习 Go,我尝试将一系列接受数据库连接作为第一个参数的函数重构为结构方法和一些更“惯用”的 Go 语言。
现在我的“数据存储”方法是这样的:
func CreateA(db orm.DB, a *A) error {
db.Exec("INSERT...")
}
func CreateB(db orm.DB, b *B) error {
db.Exec("INSERT...")
}
Run Code Online (Sandbox Code Playgroud)
这些功能运行得很好。orm.DB是go-pg 的数据库接口。
由于这两个函数接受数据库连接,我可以传递实际连接或事务(实现相同的接口)。我可以确定发出 SQL INSERT 的两个函数在同一事务中运行,从而避免在其中一个函数失败时数据库中出现不一致的状态。
当我决定阅读更多有关如何更好地构造代码并使其“可模拟”以备不时之需时,麻烦就开始了。
所以我用谷歌搜索了一下,阅读了《Go 中的实用持久性:组织数据库访问》一文,并尝试重构代码以使用正确的接口。
结果是这样的:
type Store {
CreateA(a *A) error
CreateB(a *A) error
}
type DB struct {
orm.DB
}
func NewDBConnection(p *ConnParams) (*DB, error) {
.... create db connection ...
return &DB{db}, nil
}
func (db *DB) CreateA(a *A) error {
... …Run Code Online (Sandbox Code Playgroud) 给定table_a这样的:
id | name
----+------
1 | aaaa
2 | bbbb
3 | cccc
Run Code Online (Sandbox Code Playgroud)
我显然可以发出以下查询:
SELECT * FROM table_a WHERE name IN ('aaaa', 'bbb');
Run Code Online (Sandbox Code Playgroud)
但是给定table_b这样的:
id | data
----+------------------
1 | {"name": "aaaa"}
2 | {"name": "bbbb"}
3 | {"name": "cccc"}
Run Code Online (Sandbox Code Playgroud)
我如何发出查询“给我所有包含键值的值包含在此值列表中的行?”
我知道我可以使用jsonb 运算符@>来检查每个组合,但是不幸的是,我必须发出与要检查的值数量一样多的查询。有没有办法在一个查询中做到这一点?
更新:
我马上找到了解决方案:
select * from table_b where data #>> '{name}' IN ('aaaa', 'bbb');
Run Code Online (Sandbox Code Playgroud)