2016-05-15 18 views
5
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()); 

Próbuję napisać kod, który pozwoli moje zapytanie do podjęcia trzech opcjonalnych identyfikatorów na przykład chciałbym kwerendy ostatecznieJak napisać opcjonalny gdzie klauzule JOOQ

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

jednak , chciałbym również możliwość bycia w stanie wykluczyć jakiekolwiek z identyfikatora

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

lub

select * from my_table where ID3=7 

Problem polega na tym, że pierwszy „gdzie” klauzula należący do id jednym i reszta ANDS więc jeśli zrobiłem if i usunąłem Gdzie więc będę tylko z lewej

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()); 

i to by nie działało.

Próbowałem szukać czegoś takiego jak where id = * gdzie * zasadniczo nie ma filtra, ale nie mogłem znaleźć czegoś takiego.

Odpowiedz

5

jOOQ sprawia, że ​​pisanie SQL wygląda tak, jakby było statyczne, wbudowane SQL. Ale tak nie jest. Każde zapytanie jOOQ jest dynamicznym zapytaniem SQL złożonym z drzewa wyrażeń - po prostu tego nie zauważasz.

Metoda przyjmuje argument Condition, którego nie trzeba tam umieszczać, używając klauzuli WHERE.Można skonstruować go przed zapytania:

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)); 

można teraz przekazać, że na zapytanie:

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

Istnieją również sposoby eksploatacji w DSL, takie jak:

to również udokumentowane tutaj w instrukcji: http://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql/

+0

Próbuję go ale z jakiegoś powodu trueCondition zawsze zwraca wartość true, więc moje zapytanie zwróci wszystko. Czy jest inny warunek do użycia? –

+1

@LukeXu: Tak, to jest celem trueCondition ... :) czy jesteś pewien, że przypisujesz każdą nową sytuację do zmiennej? Operacja and() tworzy nowy warunek. To nie zmienia lewej strony. –

+0

Ah w porządku, to ma sens, dzięki! –

2

co prosicie jest czasami sędziował jako „SQL«number»symboli wieloznacznych” lub przynajmniej można znaleźć komentarze w internecie, jeśli szukasz tego.

SQL nie pozwalają na zapis „gdzie id = *” zamiast jeśli potrzebny DDL pozostać statyczny można naśladować go wykonując Sprawdzić zakres jak

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) 

więc teraz trzeba przejechać łącznie 6 parametrów do zapytania, jeśli chcesz wykonać dopasowanie względem id1, ustawisz zarówno fk_id1_low, jak i fk_id1_high na wartość, którą chcesz dopasować. Jeśli nie chcesz dopasować się do id1, ustaw fk_id1_low na minimalną możliwą wartość, a fk_id1_high na maksymalną możliwą wartość. Jedną z rzeczy, którą należy rozważyć, jest to, w jaki sposób wynikowe zapytanie zostanie przetworzone przez silnik bazy danych, ponieważ może zostać wykonana duża ilość dodatkowej pracy.

Z JOOQ inną możliwą odpowiedzią jest odejście od płynnego interfejsu, aby można było zbudować zapytanie za pomocą instrukcji if..then partycje warunkowe.

Powiązane problemy