はじめに
Javaであれば公式ドキュメントに例があります。
http://iciql.com/examples/#inner-join-statements
自分は同じことをkotlinで実装する際に嵌ったためメモとして残します。
実装
例えば1個目の例のようにCustomerテーブルとOrderテーブルをinner joinしてCustomerの全カラムを取得したい場合は
val customersWithLargeOrders =
db.from(c).
innerJoin(o).on(c.customerId).is(o.customerId).
where(o.total).greaterThan(BigDecimal("500.00")).
groupBy(c.customerId).select();
とすればOKです。
ですがよくあるパターンで「全てのテーブルにIDという名前のカラムが存在する」状況(※)だとこの書き方だと"Column 'id' in field list is ambiguous"などのエラーが発生し失敗します。
※他に主キーとして相応しいカラムがあるならidカラムを作るよりもそっちを主キーにした方が良いと思います。
Iciqlにはasを使ってカラム名を一時的にリネームする方法が多分ありません。ですので公式ドキュメント2つ目の例
List<CustOrder> orders =
db.from(c).
innerJoin(o).on(c.customerId).is(o.customerId).
where(o.total).lessThan(new BigDecimal("500.00")).
orderBy(1).
select(new CustOrder() {{
customerId = c.customerId;
orderId = o.orderId;
total = o.total;
}});
のように必要なカラムだけを抜き出すためのクラス(を継承した匿名クラス)をselectに渡す必要があります。
例で波括弧が2重になっているのは誤字ではなく匿名クラス内にイニシャライザがあるということです。
これをkotlinで再現する場合、まずselectに渡すためのクラスは
open class Hoge() {
var fuga : Int = 0
}
のように
- openをつける(でないとイニシャライザでメンバ変数を参照できない)
- valではなくvarにする(イニシャライザで代入が行われるため)
必要があります。
上の例で2重括弧となっていた箇所は
{
init {
//ここに代入処理を書く
}
}
とします。
終わりに
正直ほぼkotlinの文法の話という気がしますが、普段Javaばかり使っていてkotlinについて理解していないことが多いこと及びJavaでも普段イニシャライザは全然使わないのでそもそもどう調べれば良いのか分からず苦労しました。
Iciqlについては日本語資料が少ないので同じようにkotlin × Iciqlで悩んでいる人たちのために時々メモを残していきたいと思います。