前回の記事では、sqlxライブラリでプレースフォルダを使ったINSERTする際に、
map[string]interface{}
を使ってましたが、職場の人から「構造体でもできる」ということを教わりました。
今回はそのメモです。
まずはおことわり
- 「使えればいい」レベルでの内容ですので、セキュリティやコード品質は無視しております。ご了承ください。
結論から
- INSERT,UPDATEに使用するための構造体を用意する。
- 構造体に
db:"カラム名"
タグを明記しておく。 - SQL側でのプレースフォルダの変数名は構造体タグ
db:"カラム名"
の「カラム名」と同じにする。 - あとは通常通りNamedしたり、NamedExecして実行する。
構造体のタグdb:"カラム名"
はSELECT文の受け手となる構造体を定義するときに使われますが、INSERT,UPDATEのプレースフォルダにも使えることを今回初めて知りました。
例題のソース
実例 INSERTの場合
// INSERTに値を入れるための構造体
type HogeTableIn struct {
ID int `db:"id"`
Name string `db:"name"`
Birthday string `db:"birthday"`
}
// INSERT SQLを定義する。
// プレースフォルダの変数名は構造体のタグ`db:"***"`で定義した名称と同じにする。
sql := `INSERT INTO hoge_table (id, name, birthday) VALUES (:id, :name, :birthday);`
// 構造体を宣言し、値を詰めておく。
in := HogeTableIn{
ID: 1,
Name: "alpha",
Birthday: "2022-01-23",
}
db := {sqlxでDBに接続してハンドルを受け取る}
_, err := db.NamedExec(sql, in)
if err != nil {
return err
}
実例 UPDATEの場合
// UPDATEに値を入れるための構造体
type HogeTableIn struct {
ID int `db:"id"`
Name string `db:"name"`
}
// UPDATE SQLを定義する。
// プレースフォルダの変数名は構造体のタグ`db:"***"`で定義した名称と同じにする。
sql := `UPDATE hoge_table SET name = :name WHERE id = :id;`
// 構造体を宣言し、値を詰めておく。
in := HogeTableIn{
ID: 1,
Name: "bravo",
}
db := {sqlxでDBに接続してハンドルを受け取る}
_, err := db.NamedExec(sql, in)
if err != nil {
return err
}
実例 バルクインサートも出来ます。
type HogeTableIn struct {
ID int `db:"id"`
Name string `db:"name"`
Birthday string `db:"birthday"`
}
sql := `INSERT INTO hoge_table (id, name, birthday) VALUES (:id, :name, :birthday);`
// 構造体配列を宣言し、値を詰めておく。
in := []HogeTableIn{
{
ID: 2,
Name: "charlie",
Birthday: "2022-04-05",
},
{
ID: 3,
Name: "delta",
Birthday: "2022-06-07",
},
}
db := {sqlxでDBに接続してハンドルを受け取る}
_, err := db.NamedExec(sql, in)
if err != nil {
return err
}
以上となります。