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?

SQLBoilerでJoin系のクエリを実行したい時はこうしよう

1
Posted at

SQLBoilerでInnerJoinやLeftJoinをしたいとき、qmパッケージのInnerJoinとLeftJoinなどを使いがちです。

ただここで問題があって、

このqmパッケージの関数を使ってJoinしようとすると以下のように書けます。

models.Users(
    qm.InnerJoin("posts ON posts.user_id = users.id"),
).All(ctx, db)

つまり、生のSQL文字列を書く必要があるのです。

何が問題なのかというと、

  • 可読性が低い
    • テーブル名やカラムを直書きしている時点でSQLBoilerを活用しきれていない
  • タイポの温床となる
  • DRYじゃない
    • 同じような結合条件があると、このような文字列を大量に書く必要がある

正直今上げた問題点はかなりコードを書く上では辛いです。

ではどうするか?

関数化しておこう!

よく使うJoinのパターンを関数化(ヘルパー化)しておきましょう。

毎回 fmt.Sprintf や生の文字列を書くのではなく、構造化された引数を受け取る関数を用意することで、コードの見通しが良くなります。

例えば、以下のようなInnerJoin関数を作っておけば、

func InnerJoin(joinTable, baseTable, joinTableColumn, baseTableColumn string) qm.QueryMod {
	return qm.InnerJoin(fmt.Sprintf("%s ON %s.%s = %s.%s",
		joinTable,           // joinTable: 結合するテーブル名
		joinTable,           
		joinTableColumn,     // joinTableColumn:結合するテーブルのカラム
		baseTable,           // baseTable: 結合元のテーブル名 
		baseTableColumn,     // baseTableColumn:   結合元のテーブルのカラム
	))
}

以下のように使うことができます。

以下はTagsテーブルに対して、ContentsTagsテーブルをInnerJoinしたい時の例です。

	models, err := models.Tags(
		InnerJoin(
			models.TableNames.ContentsTags,
			models.TableNames.Tags,
			models.ContentsTagColumns.TagID,
			models.TagColumns.ID,
		),

このように書くことで次のようなメリットが得られます。

  • 安全性の向上
    • SQLBoilerが生成する models.TableNamesmodels.TagColumns といった定数と組み合わせることで、文字列のタイポを撲滅できます
  • 変更に強い
    • 万が一カラム名が変更になっても、定数を使っていればコンパイルエラーで検知できる可能性が高まります
  • 可読性
    • 「どのテーブル」「どのカラム」で結合しているかが引数として明確になります

LeftJoinやRightJoinも同様に関数化しておけばかなり便利です

まとめ

SQLBoilerのqmパッケージでJoinを行う際、生のSQL文字列を直書きするとタイポや変更漏れのリスクが生じます。

この課題を解決するために、SQLBoilerが生成するテーブル名やカラム名の定数を引数に取れるヘルパー関数を自作すること型安全性や可読性の高いコードを実現できます。


弊社ウェブサイトでは、技術記事の他にもデザインナレッジや日々の気づき等を配信しています。

カジュアル面談も実施中です。お気軽にお問い合わせください。

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?