1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

reflectフリーなクエリビルダーsqllaにORM-likeなメソッドを追加した

Last updated at Posted at 2016-10-08
1 / 19

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

  • 補完が効く
    • 当然型も表示される
      https://gyazo.com/a6e77e30a8ca5d774bb8969c5c06f861

ここまでは今まで出来ていたこと


どのように使っていたかというと

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)
}

:innocent: だるい :innocent:


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)

:innocent: これで十分やろ :innocent:


まだ不十分かつ入れたいと思っているもの

  • リレーション
    • 単純なアソシエーションメソッドではなくJOINで一気にとってくるやつ
  • ORとCASEとHAVING
  • Prepare
  • 英語のドキュメント
  • メモリアロケーション削減

そんなわけで頼む使って見てくれ頼む:pray:

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?