emahiro/b.log

Drastically Repeat Yourself !!!!

久しぶりに sqlx を使ったら色々忘れてた

Overview

すごい久しぶりに sqlx を使ったら色々忘れてたので備忘録です。

github.com

driver は blank import しておかないといけない

driver の種類は下記を参照 https://github.com/golang/go/wiki/SQLDrivers

例えば MySQL を Driver として選択したい場合には MySQL を使うパッケージで

import _ "github.com/go-sql-driver/mysql"

とする必要があります。
これは別に sqlx に限った話じゃないですが完全に忘れてました笑

StructScan に Slice は当てられない

sqlx のメリットの1つに db.Query を使ったときにマッピングするカラムを全て指定しないといけないと言う標準の sql/database のデメリットを回避し、DB のテーブルに対応する struct を定義してき、db.StructScan を使うとマッピングを自動でやってくれると言うのがあると思いますが、この db.StructScan には Struct 以外を当てることはできません。

Slice で取り出したいときは以下のようにします。

type User struct {
    id ing64 `db:"id"`
    name string `db:"name"`
    age int64 `db:"name"`
}

rows, err := db.Queryx("SELECT * FROM user WHERE age > 20")

users := make([]*User, 0, 0)

for rows.Next() {
    user := User{}
    if err := db.StructScan(&user); err != nil {
        // handle error
    }
    users = append(users, &user)
}

追記: README 見たら db.Select が使える。ORM っぽく使いたいならアリかも。

フィールドを指定しないと missing destination name エラーが発生する

取り出したいカラムは指定しろってことですね。 つまり以下のようなクエリは発行しても struct にマッピングできません。

テーブル: User
- id INT
- name VARCHAR
- age INT
type User struct {
    ID int64 `db:"id"`
    Name string `db:"name"`
}
 
rows, err := db.Queryx("SELECT * FROM user where id = ?", 1)
if err != nil {
    // error handling
}
user := User{}
for rows.Next() {
    if err := rows.SturctScan(&user); err != nil {
        // missing destination name age が発生する 
    }
}

取り出したいカラムを制限したい場合はクエリで取り出すフィールドを指定する必要があります。

type User struct {
    ID int64 `db:"id"`
    Name string `db:"name"`
}
  
rows, err := db.Queryx("SELECT id, name FROM user where id = ?", 1)
if err != nil {
    // error handling
}
user := User{}
for rows.Next() {
    if err := rows.SturctScan(&user); err != nil {
      // missing destination name age が発生する 
    }
}