GoのORMのSQLBoilerでIN句の使い方と2通りの方法について

こんにちは!株式会社Voicyでバックエンドエンジニアをしているたーふーと申します。
簡単に自己紹介をさせていただくと、自分は去年の9月にVoicyに入社したので、入社して半年くらいになります!

今回はGoのORMであるSQLBoilerでWhereInの使い方とその2通りの方法についてお話しできればと思います!

自分自身Goを実務で利用したのはVoicyに入社してからなので歴は浅いのですが、、
その中でSQLBoiler関連の情報が少ないように感じた経緯があり、今回この記事を書かせていただきます。

なので同じような方の参考になれば幸いです!もし興味があれば是非ご覧ください!!

SQLBoilerとは?

まずそもそもSQLBoilerとは何か説明します。

SQLBoilerとは名前から想像できると思いますが、Goで使われるORMライブラリの1つです。
Goでは他にも有名なGORMなどのORMがありますが、VoicyではSQLBoilerを採用しています!

Go初心者でGoのORM関連について気になる方は以下の記事が参考になったので、見てみてください!

zenn.dev

またSQLBoilerの特徴としては以下が挙げられています。

  • DBのスキーマを読み取り、コードを自動生成する
  • 静的型付けのため動作が高速

※参考 github.com

ちなみに以前下記記事も取り上げているので、もしご興味があれば!

tech-blog.voicy.jp

IN句とは?

次にIN句について解説します!
(この記事を見る皆さんはご存知だと思いますが、、)

IN句とはSQLのSELECT文で複数のor条件をまとめる構文です。(Where in)

例えば以下のような複数のuser情報を取得するクエリがあります。

SELECT * FROM t_user WHERE id = "1" OR name = "2";

上記を以下の様な書き方にまとめることができます!

SELECT * FROM fruit WHERE name IN("1","1");

SQLBoilerでIN句を利用する方法①

では本題のSQLBoilerでIN句を利用するには2通りの方法があります。

まず1つ目は結論以下の様に記述します。

結論以下のように記載すれば簡単に利用可能です!

m, err := models.Users(
    qm.WhereIn("id IN ?", ids...),
).AllG(ctx)

ただこちら1つ問題点があり、それはids...の部分です。 こちらは一見単純にidをスライス形式で入れておけば良さそうに見えまが、その場合だとうまく動作しません。。

なぜならこちらには配列にした値を引数に持たないといけないからです。。 なので事前に以下の様な処理を毎度入れる必要があります・・

ids := make([]interface{}, len(userIDs))
for i, userID := range userIDs {
    ids[i] = userID
}

SQLBoilerでIN句を利用する方法②(おすすめ)

基本複数の同一情報を持つ場合、スライス形式で持たせることが多いと思います。 なのでこれを毎回毎回変換処理する①の方法は手間になると思います。

その場合は以下の様な記載をすれば解決できます!!

m, err := models.Users(
  models.TUserWhere.ID.IN(ids),
).AllG(ctx)

SQLBoilerはコード生成時に各テーブルの情報毎に定義ファイル的なものを作成します。 その中のIN関数を利用すれば、スライスのままで対応が可能です!! (ちなみにINの中でやっていることは、上記の変換処理をしてqm.WhereIn渡すという①と同じことをしているだけでした‥w)

しかし毎回の変換処理はこれで消すことができますので、有効活用できます!

終わりに

最後まで記事をご覧いただきありがとうございます!
この記事が少しでも参考になれば幸いです!