Jak efektywnie wykonywać przetwarzanie masowe z wykorzystaniem biblioteki MyBatis?

28 lipca 2015, Andrzej Karczyński

Tworząc oprogramowanie prawdopodobnie często spotykasz się z zagadnieniem masowego wykonywania operacji na bazie danych (np. masowy update, insert, delete). Okazuje się wtedy, że wykonywanie pojedynczych instrukcji zajmuje dużo czasu z uwagi na to, że każda pojedyncza operacja wiąże się z przesłaniem zapytania do bazy danych i czekania na wyniki. Możesz rozwiązać te problemy z wykorzystaniem przetwarzania batchowego / masowego / wsadowego (operacja występuje pod wieloma nazwami). Polega to na tym, że przygotowujemy paczkę instrukcji / operacji do wykonania (tzw. batch) i wysyłamy wszystko w jednym żądaniu do bazy danych.

Okazuje się, że do przetwarzania masowego / batch’owego nie musimy odwoływać się do „gołego” JDBC, ale możemy też użyć ulubionej w Pretius biblioteki do komunikacji z bazą danych, czyli MyBatis (https://mybatis.github.io/). W tym poście opiszę jak można efektywnie i wydajnie zrealizować przetwarzanie masowe z wykorzystaniem MyBatis i jakie mogą pojawić się problemy związane z tego typu operacjami. Jeśli znasz już trochę mechanizmy działania MyBatis oraz Spring zapraszam do dalszej lektury.

Konfiguracja MyBatis do przetwarzania batchowego

Na początek potrzebujemy skonfigurować sesję MyBatisa:

Potrzebne są dwa szablony (templates) sesyjne dla MyBatis:

  • standardowy – do standardowych, pojedynczych operacji
  • batchowy – do przetwarzania wsadowego / masowego

UWAGA: w jednej transakcji możesz używać tylko jednego rodzaju przetwarzania.

Standardowo wszystkie mappery MyBatis używają domyślnego szablonu sesyjnego, więc działają bez wykorzystania przetwarzania batchowe’go.

Jednego mappera chcemy dodatkowo używać w sesji batchowej, więc konieczne jest stworzenie osobnej instancji tego mappera:

Przykładowy mapper:

W powyższym przykładzie zauważysz, że dodałem do niego dodatkową metodę flush, żeby móc kontrolować moment wysyłki do bazy danych – np. w sytuacji, gdy chcemy dzielić batche po 1000 elmentów (możliwości obsługi flush działa od MyBatis 3.3.0).  Metoda flush zwraca listę wszystkich przetworzonych wyników batcha, czyli generalnie liczby przetworzonych wierszy (oczywiście szczególnie przydatne przy masowych update’ach / aktualizacjach – np. żeby zaraportować liczbę zmodyfikowanych wierszy).

Przykład użycia metody flush w serwisie:

Metoda flush zadziała automatycznie na koniec transakcji albo przy każdym wywołanym select’cie.

Potencjalne problemy i jak sobie z nimi radzić

Użycie mechanizmu generated keys z bazą Oracle

Jeśli chcesz użyć mechanizmu „generated keys”, czyli kluczy generowanych przez bazę danych do wstawianych rekordów, to w przypadku przetwarzania batchowego z wykorzystaniem bazy danych Oracle, driver JDBC do tej bazy rzuci wyjątkiem. W takiej sytuacji po każdym insercie konieczne jest wywołanie flush’a. Oznacza to, że w przypadku wykorzystania drivera Oracle i chęci / konieczności wykorzystania mechanizmu „generated keys” nic nie zyskujemy wykorzystując przetwarzanie batchowe do insertów. Jeśli „generated keys” nie są nam potrzebne, wtedy wywołanie flush’a również nie będzie koniecznie.

Podsumowanie

Jeśli szukasz wydajnego sposobu zapisywania danych masowo do bazy danych z Twojej aplikacji Java to MyBatis jest dobrym wyborem działającym na wyższym poziomie niż proste wywołania JDBC. Jednocześnie MyBatis daje cały szereg innych funkcjonalości do wykorzystania przy komunikacji z bazą danych, które sprawiają, że jest bardzo użytecznym i przyjaznym dla programisty narzędziem.

Tagi: , , , , , , , , , , , , , , ,

Zapraszamy do kontaktu!

Pretius jest firmą tworząca oprogramowanie wspierające biznes.
Tworzymy aplikacje webowe wykorzystując: Java, Oracle DB, Oracle Apex, AngularJS.
Skontaktuj się z nami, aby porozmawiać o tym jak możemy pomóc w realizacji Twojego projektu!