Nie rób rekurencyjnego wyszukiwania w Javie. To się nie skaluje, ponieważ będziesz wysyłać dużo zapytań do bazy danych. Użyj (pojedynczego) rekurencyjnego zapytania bezpośrednio w bazie danych, które będzie działać i skalować znacznie lepiej.
Nie określiłeś swojego DBMS, ale zapytania rekurencyjne są obsługiwane przez wszystkie nowoczesne bazy danych. Poniżej znajduje się standardowy ANSI SQL:
with recursive ancestry as (
select child, parent, 1 as level
from users
where parent = 'Grandfather' -- this is the one who logs in
union all
select c.child, c.parent, p.level + 1
from users c
join ancestry p on p.child = c.parent
)
select child, level
from ancestry
order by level desc;
Przykład:http://rextester.com/TJGTJ95905
Edytuj po ujawnieniu prawdziwej bazy danych.
W Oracle masz na to dwa sposoby.
"Tradycyjnym" sposobem jest użycie connect by
która jest znacznie bardziej kompaktową formą zapytania rekurencyjnego niż to, co wymyślił standard SQL:
select child, level
from users
start with parent = 'Grandfather'
connect by prior child = parent
order by level desc;
możesz użyj wspólnego wyrażenia tabelowego również w Oracle. Jednak nawet jeśli standard SQL wymaga słowa kluczowego recursive
aby być obowiązkowym, Oracle zdecydowało się zignorować tę część standardu, więc musisz ją usunąć. LEVEL
to pseudokolumna w Oracle, której można używać tylko razem z connect by
więc nie można tego użyć w rozwiązaniu CTE:
with ancestry (child, parent, lvl) as (
select child, parent, 1 as lvl
from users
where parent = 'Grandfather'
union all
select c.child, c.parent, p.lvl + 1
from users c
join ancestry p on p.child = c.parent
)
select child, lvl
from ancestry
order by lvl desc