[Seasar-user:16111] Re: [S2JDBC] innerJoin と leftOuterJoin で同じ Entity を指定したい

Shotaro Tsubouchi [E-MAIL ADDRESS DELETED]
2008年 10月 25日 (土) 21:21:38 JST


ショータローこと坪内です。

いやはや、こちらこそ寝ぼけまなこであまり考えずに書いてました。。

> と JOIN ON 〜 で条件を指定するのではなく,
> WHERE で指定すべきかと.

タイプセーフな書き方で何とか、とか考えているうちにこうなってました。
確かに本来は WHERE で指定するものなのでしょうが、
スマートに書けなさそうだったので。。

> このケースで片方が leftOuterJoin なのは作為的な
> 気がします.(^^;

このケースだと leftOuterJoin である必要は全然無かったですね。。
本来的に発行されるべきクエリーは、副問い合わせの必要はなく、

select T1_.*, T3_.*
  from FOO T1_
 inner join BAA T2_ on T2_.FOO_ID = T1_.ID
 inner join BAA T3_ on T3_.FOO_ID = T1_.ID
 where T2_.ID = 1

こうではないかと思います。と考えると、

・フェッチしない結合は重複を許す
・WHERE で JOIN の番号を指定可能にする

ができれば良くて、

select() // jdbcManager.from(Foo.class)
    .innerJoin(baaList(), false)
    .innerJoin(baaList())
    .where(eq(baaList(2).baaId(), 1))
    .getResultList();

みたいな感じで行けるようになったりしないですかね?
かなり希望的観測ですが。


Koichi Kobayashi さんは書きました:
> 小林 (koichik) です.
> 
> 出かける支度中で慌て気味なので変なこと
> 書いてるかもしれませんがご容赦ください.
> 
> Date:    Sat, 25 Oct 2008 09:53:23 +0900
> From:    Shotaro Tsubouchi <[E-MAIL ADDRESS DELETED]>
> To:      [E-MAIL ADDRESS DELETED]
> Subject: [Seasar-user:16109] [S2JDBC] innerJoin と leftOuterJoin で同じ Entity を指定したい
> 
>> 親子関係にある Entity、Foo と Baa において、
>> ID が 1 の Baa を持っている Foo を取得し、
>> その Foo 毎に関連する Baa も取得したい場合、
> 
> ここで「ID が 1 の Baa を持っている」は
> 結合条件ではなく選択条件なので,
> 
>> select() // jdbcManager.from(Foo.class)
>>     .innerJoin(baaList(), false, eq(baaList().baaId(), 1))
>>     .leftOuterJoin(baaList())
>>     .getResultList();
> 
> と JOIN ON 〜 で条件を指定するのではなく,
> WHERE で指定すべきかと.
> 
> となると EXISTS または IN で相関福問い合わせを
> 使うことになりますが,S2JDBC の SimpleWhere は
> サポートしていないので,where(String, Object...) を
> 使うことになってしまいます.
> 
> 相関福問い合わせは SQL だと
> 
> 〜 where exists (select * from BAA where BAA_ID = ? and FOO_ID = T1_.FOO_ID)
> 
> みたいになります.
> # この例は多対多関連なので本当は FOO_ID なんて
> # ないのかもしれませんが.
> 
> ここで T1_ は主問い合わせの Foo のエイリアスで,
> S2JDBC が割り振るものです.
> S2JDBC は where(String, Object...) に渡された
> 文字列にこのエイリアスを自動的に割り振るので
> T1_ は省略できます.
> 
> select() // jdbcManager.from(Foo.class)
>     .innerJoin(baaList())
>     .getResultList();
>     .where("exists (select * from BAA  where BAA_ID = ? and FOO_ID = fooId", 1)
>     .getResultList();
> 
> のようになるかと思うのですが,試してないので
> 怪しいかも.
> カラム名とプロパティ名が入り乱れて気持ち悪い...
> 
> 
>> ひとまず、AutoSelectImpl の 774 行目をコメントアウトして
>> 例外を無視してみたところ、想定していたクエリーを発行できました。
>> 結合条件の重複チェックが、innerJoin と leftOuterJoin で
>> 分かれていれれば良いんですかね?
> 
> このケースで片方が leftOuterJoin なのは作為的な
> 気がします.(^^;
> 
> 制約をゆるめるなら,フェッチしない結合は重複を
> 許すということが考えられますが,フェッチしない
> ということは選択条件のためということになり,
> それなら WHERE 句で頑張るのが筋かなと.
> そのためには相関福問い合わせのサポートを向上する
> 必要があって悩ましいですが.
> 
> 


Seasar-user メーリングリストの案内