LoginSignup
7
5

More than 5 years have passed since last update.

Golanのsqlxで名前付きパラメタを扱う

Last updated at Posted at 2019-01-15

golangにはsqlxというdatabase/sqlの拡張機能を提供するライブラリがあります。

このライブラリはSelectクエリを発行する際に同時にstructへ結果をマッピングしてくれる機能を提供しており非常に便利なのですが、READMEを見てみると名前付きクエリを発行しつつ、structへのマッピングする方法が書かれていません。

※MySQLだとsql.Namedが利用出来ないため、名前付きクエリを実現するにはこのようなライブラリに頼る必要があります。

structへのマッピングを行うクエリ
type User struct {
    NameA string `db:"name_a"`
    NameB string `db:"name_b"`
}

query := `SELECT * FROM users WHERE name_a = ? OR name_b = ?`

var user User

// 同じ名前を重複して指定しないといけない。
if err := sqlx.Get(&user, query, "Tom", "Tom"); err != nil {
    log.Print(err)
}
REAMEで紹介されている名前付きクエリの実行方法
query := `SELECT * FROM users WHERE name_a = :name OR name_b = :name`

// 名前付きクエリを発行する機能はあるものの、結果がsql.Rowsで返ってきてしまう…
rows, err = db.NamedQuery(query, map[string]interface{}{"name": "Tom"})

じゃあ方法が無いのかと言うとそういうわけではなくsqlx.Namedという機能が提供されており、これを利用することでstructへのマッピングと名前付きクエリをあわせて行えるようになります。

query := `SELECT * FROM users WHERE name_a = :name OR name_b = :name`
bindParams := map[string]interface{}{
    "name": "Tom",
}

// sqlx.Namedを利用すると、名前付きパラメタが?に置換され、それに対応するバインドパラメタのsliceが返される
query, params, err := sqlx.Named(query, bindParams)
if err != nil {
    log.Print(err)
}
log.Print(query)  // SELECT * FROM users WHERE name_a = ? OR name_b = ?
log.Print(params) // ["Tom" "Tom"]

var user User
if err := sqlx.Get(&user, query, params...); err != nil {
    log.Print(err)
}
7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5