如何在JOOQ中编写OPTIONAL where子句

时间:2016-05-15 12:40:00

标签: java-8 jooq

  Dim query As IEnumerable(Of clsWidget)
  query = WidgetSource.Where(Function(widget) widget.name = txtNewName.Text)

  If query.Count > 0 Then
    Debug.Print("Tried to add a widget that already in the collection")
  End If

我尝试编写一些代码,允许我的查询采用三个可选ID,例如我希望查询最终成为

List<MyTable> result = DSL.using(configuration())
                .select()
                .from(MY_TABLE)
                .where(MY_TABLE.ID1.equal(pk_id1))
                        .and(MY_TABLE.ID2.equal(fk_id2))
                        .and(MY_TABLE.ID3.equal(fk_id3))
                .orderBy(MY_TABLE.ID.asc())
                .limit(limit)
                .fetchInto(MY_TABLE)
                .map(mapper());

但是,我还希望能够排除任何id

select * from my_table where ID1=5 and ID2=6 and ID3=7 .... etc 

select * from my_table where ID2=6 and ID3=7 

问题在于第一个&#34;其中&#34;子句属于id一,其余的是ands所以如果我做了一个if语句,我删除了那里,那么我只剩下了

select * from my_table where ID3=7

它不会起作用。

我试图寻找像List<MyTable> result = DSL.using(configuration()) .select() .from(MY_TABLE) .and(MY_TABLE.ID2.equal(fk_id2)) .and(MY_TABLE.ID3.equal(fk_id3)) .orderBy(MY_TABLE.ID.asc()) .limit(limit) .fetchInto(MY_TABLE) .map(mapper()); 这样的东西,其中*基本上没有过滤器,但我找不到那样的东西。

2 个答案:

答案 0 :(得分:14)

jOOQ使编写SQL感觉好像是静态的嵌入式SQL。但事实并非如此。每个jOOQ查询都是一个由表达式树组成的动态SQL查询 - 您只是没有注意到它。

SelectWhereStep.where(Condition)方法采用Condition参数,您不必使用WHERE子句放在那里。您可以在查询之前构建它:

Condition condition = DSL.trueCondition();
if (something)
    condition = condition.and(MY_TABLE.ID1.equal(pk_id1));
if (somethingElse)
    condition = condition.and(MY_TABLE.ID2.equal(fk_id2));
if (somethingOther)
    condition = condition.and(MY_TABLE.ID3.equal(fk_id3));

您现在可以将其传递给您的查询:

List<MyTable> result = 
DSL.using(configuration())
   .select()
   .from(MY_TABLE)
   .where(condition)
   .orderBy(MY_TABLE.ID.asc())
   .limit(limit)
   .fetchInto(MY_TABLE)
   .map(mapper());

DSL中也有实用方法,例如:

手册中也记录了这一点:http://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql/

答案 1 :(得分:2)

您要求的内容有时会被称为&#34; SQL&#39;数字&#39;通配符&#34;或者至少你可以在网上找到评论。

SQL不允许你写&#34;其中id = *&#34;相反,如果你需要你的DDL保持静态,你可以通过像

这样的范围检查来模拟它
select * from table
  where
    (my_table.id1 >= fk_id1_low and my_table.id1 <= fk_id1_high) and
    (my_table.id2 >= fk_id2_low and my_table.id2 <= fk_id2_high) and
    (my_table.id3 >= fk_id3_low and my_table.id3 <= fk_id3_high)

所以现在你要向查询传递总共6个参数,如果你想对id1进行匹配,你会将fk_id1_low和fk_id1_high都设置为你想要匹配的值。如果您不想与id1匹配,则将fk_id1_low设置为最小可能值,并将fk_id1_high设置为最大可能值。您必须考虑做的一件事是数据库引擎如何处理生成的查询,因为可能会执行大量额外工作。

使用JOOQ,另一个可能的答案是远离流畅的界面,以便您可以使用if..then条件部分构建查询。