sqllaとは
- Go向けのクエリビルダー
- 事前にDBのスキーマをstruct tagを用いて定義してクエリビルダーのコードを自動生成
$ go get github.com/mackee/go-sqlla/cmd/sqlla
//go:generate sqlla
//+table: user
type User struct {
ID uint64 `db:"user"`
Name string `db:"name"`
Age uint32 `db:"age"`
IsAlive bool `db:"is_alive"`
}
$ go generate
コード生成のメリット その1
- 型解決がコンパイル時にできる
- スキーマ定義とは違う型の値を入れようとするとコンパイルエラー
- reflectを使わなくても良いのでreflectを使うクエリビルダー(github.com/Masterminds/squirrel など)に比べて高速
コード生成のメリット その2
ここまでは今まで出来ていたこと
どのように使っていたかというと
query, args, err := NewUserSQL().Select().ID(uint64(1)).ToSql()
if err != nil {
return fmt.Errorf("unexpected user query build error: %s", err)
}
row := db.QueryRow(query, args...)
err = row.Scan(&u.ID, &u.Name, &u.Age)
if err != nil {
return fmt.Errorf("user query execute error: %s", err)
}
だるい
ORM-like methods
一般的なORMの機能
- オブジェクト/構造体への結果のマッピング
- オブジェクト/構造体に対応するDB内のデータへの操作メソッドの付加
- 言語の構文を利用したSQLの組み立て
- 接続/トランザクション管理(コネクションプール / nested transactionなど)
- リレーション
- schemaのmigration
今までのsqllaの機能
オブジェクト/構造体への結果のマッピングオブジェクト/構造体に対応するDB内のデータへの操作メソッドの付加- 言語の構文を利用したSQLの組み立て
接続/トランザクション管理(コネクションプール / nested transactionなど)リレーションschemaのmigration
sqllaのORM-like method
- オブジェクト/構造体への結果のマッピング <- New!
- オブジェクト/構造体に対応するDB内のデータへの操作メソッドの付加 <- New!
- 言語の構文を利用したSQLの組み立て
接続/トランザクション管理(コネクションプール / nested transactionなど)リレーションschemaのmigration
クエリを組み立てて直接structを取得
u, err := NewUserSQL().Select().ID(uint64(1)).Single(db)
複数行を返すクエリ
// SELECT * FROM user WHERE is_alive = 1;
users, _ := NewUserSQL().Select().IsAlive(true).All(db)
for _, u := range users {
fmt.Printf("id: %d, name: %s\n", u.ID, u.Name)
}
構造体からUPDATE文の発行
u, _ := NewUserSQL().Select().ID(uint64(1)).Single(db)
// UPDATE user SET is_alive = 0 WHERE id = 1;
// SELECT * FROM user WHERE id = 1;
uu, _ := u.Update().SetIsAlive(false).Exec(db)
DELETE文
u, _ := NewUserSQL().Select().ID(uint64(1)).Single(db)
// DELETE FROM user WHERE id = 1;
err := u.Delete(db)
これで十分やろ
まだ不十分かつ入れたいと思っているもの
- リレーション
- 単純なアソシエーションメソッドではなくJOINで一気にとってくるやつ
- ORとCASEとHAVING
- Prepare
- 英語のドキュメント
- メモリアロケーション削減