database/sql和database/sql/driver中的命名参数

Eve*_*man 5 sql database driver go neo4j

我试图弄清楚在go的内置数据库/ sql包中使用命名参数的模式是什么.我查看了oracle驱动程序,但它似乎只是C库的包装器.让人们以优雅的方式解决这个问题吗?到目前为止,我刚刚解决该问题通过将工作{0},{1}作为单元测试的参数,但它肯定会是不错的能够正常使用他们作为map[string]interface{}什么的.有没有人有一个看似惯用的想法或实现?

供参考,这是一个测试:

db := testConn()
stmt, err := db.Prepare("return {0} as int1, {1} as int2")
if err != nil {
   t.Fatal(err)
}
rows, err := stmt.Query(123, 456)
if err != nil {
   t.Fatal(err)
}
rows.Next()

var test int
var test2 int
err = rows.Scan(&test, &test2)
if err != nil {
   t.Fatal(err)
}
if test != 123 {
   t.Fatal("test != 123;", test)
}
if test2 != 456 {
   t.Fatal("test2 != 456;", test2)
}
Run Code Online (Sandbox Code Playgroud)

而我正在做的Query是:

func (stmt *cypherStmt) Query(args []driver.Value) (driver.Rows, error) {
   cyphReq := cypherRequest{
      Query: stmt.query,
   }
   if len(args) > 0 {
      cyphReq.Params = make(map[string]interface{})
   }
   for idx, e := range args {
      cyphReq.Params[strconv.Itoa(idx)] = e
   }
...
Run Code Online (Sandbox Code Playgroud)

Gor*_*nek 8

我在数据库/ sql上使用包装器,名为sqlx https://github.com/jmoiron/sqlx 你可以在这里查看他是如何做到的.

有关如何选择元组的示例

type Person struct {
    FirstName string `db:"first_name"`
    LastName  string `db:"last_name"`
    Email     string
}
jason = Person{}
err = db.Get(&jason, "SELECT * FROM person WHERE first_name=$1", "Jason")
fmt.Printf("%#v\n", jason)
// Person{FirstName:"Jason", LastName:"Moiron", Email:"jmoiron@jmoiron.net"}
Run Code Online (Sandbox Code Playgroud)

有关如何插入元组的示例

dude := Person{
    FirstName:"Jason", 
    LastName:"Moiron", 
    Email:"jmoiron@jmoiron.net"
}
 _, err = db.NamedExec(`INSERT INTO person (first_name,last_name,email) VALUES (:first,:last,:email)`, dude)
Run Code Online (Sandbox Code Playgroud)


and*_*olm 1

可以创建一个map[string]interface{}类型driver.Valuer{}来将其序列化为 a []byte,然后将其转换回驱动程序中。

但这是低效且不惯用的。由于无论如何您的驱动程序都会以非标准方式使用,因此最好忘记数据库/sql 并编写一个具有完全自定义接口的包。