Pobrać wiele obiektów z bazy w Hibernate/Spring Data JPA

0

Cześć, mam taki kod w aplikcji, który pobiera wielu użytkowników na raz i zapisuje do ArrayList. Brakuje niektórych ID po usunięciu użytkownika z bazy, więc za każdym razem sprawdzam czy użytkownik o tym ID został pobrany. Wydaję mi się to nieefektywne, tak samo wysyłanie zapytania dla każdego ID zamiast wysłać zapytanie, np. dla przedziału.

Czy mógłbym prosić podpowiedzi jaki byłby efektywny sposób na tego typu zapytanie w Hibernate/Spring Data JPA lub SQL?

if (lastId < 24)
{
    for (int i = 0; i < lastId; i++)
    {
          User user = repository.findUserById(lastId - i);
          if (user != null)
          {
               users.add(user);
          }
     }
}
else
{
      ...
}

Spring Data JPA

1

Trzymanie użyktowników w takich pseudo-cache jest conajmniej dziwne. Zastanowiłbym się w ogóle na sensem robienia tego.
Jeśli chodzi o redukcję złożoności obliczeniowej, możesz trzymać nie List<User> users a Map<Integer, User> usersById i sprawdzać czy Map#keySet posiada dany klucz.

Żeby pobrać wszystkich użytkowników możesz zrobić findUserByIdIn(List<Integer)
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repository-query-keywords

1

Jw. po co Ci ta lista? Jeśli chcesz ograniczyć liczbę odpytań bazy, to są na to lepsze sposoby (off-heap cache, 2nd level cache, itd)

0

@Tyvrel: chodzi mi o to, że nie mogę z góry założyć listy z ID, bo w tym czasie ktoś mógł usunąć z bazy i mamy np. ID: 1, 2, 3, 6, 7, 11, a nie 1, 2, 3, 4, 5, 6 itd. Nie wiem jak to ugryźć w Javie i nie wiem czy nie lepiej zrobić takie zapytanie w SQL. Co masz na myśli przez pseudo-cache? Później lista jest parsowana do JSON i zwracana przez API.

@Charles_Ray: żeby sparsować do JSON i zwracać przez API. Teraz wygląda to tak, że aplikacja wykonuje pojedyncze zapytania do bazy by uzyskać listę użytkowników i nie wiem czy nie byłoby lepiej wykonać 1 zapytania typu 20 userów na raz. Wiesz jak się ma sprawdzanie czy użytkownik nie jest nullem do wydajności?

1

żeby sparsować do JSON i zwracać przez API. Teraz wygląda to tak, że aplikacja wykonuje pojedyncze zapytania do bazy by uzyskać listę użytkowników i nie wiem czy nie byłoby lepiej wykonać 1 zapytania typu 20 userów na raz.

Oczywiście, że lepiej, przecież możesz zrobić zapytanie WHERE user.id IN (...), żeby pobrać od razu N userów (jak kolega polecił 2 posty wyżej). Wydaje mi się jednak, że problem który rozwiązujesz to stronicowanie.

Wiesz jak się ma sprawdzanie czy użytkownik nie jest nullem do wydajności?

Pomijalnie. Nie optymalizuj za JIT-a.

0

@Charles_Ray: Dzięki, widziałem. Wprowadziłem was w błąd. Jednak dane będą przekazywane do do modelu i strona jest renderowana na serwerze za pomocą Thymeleaf. W tym wypadku stronicowanie z tego artykułu wydaje się mało efektywne. On tam korzysta z findAll, więc jak będę miał 20k userów to musiałbym korzystać z cache, tak?

1

Nie, stronicowanie z tego artykułu korzysta z magii Spring Data i generowane jest optymalne zapytanie wykorzystujące mechanizmy bazy danych (rownum, offset, limit). Inaczej ciężko to nazwać stronicowaniem. Zapoznaj się ze zrozumieniem ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1