0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

kotlin × Iciqlでinner joinを行う方法

Posted at

はじめに

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で悩んでいる人たちのために時々メモを残していきたいと思います。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?