Obsługa bardzo dużej ilości danych w MyBatis

Moim celem jest zrzucenie wszystkich danych z bazy danych do pliku XML. Baza danych nie jest strasznie duża, to około 300MB. Problem w tym, że mam ograniczenie pamięci tylko 256MB (w JVM). Więc oczywiście nie mogę po prostu odczytać wszystkiego w pamięci.

Udało mi się rozwiązać ten problem używając ibatisa (tak, mam na myśli iBatis, nie myBatis) przez wywołanie go getList(... int skip, int max) wiele razy, z przyrostem skip. To rozwiązuje mój problem z pamięcią, ale nie jestem pod wrażeniem prędkości. Zmienna nazwy sugerują, że to, co metoda robi pod maską, to odczytanie całego wyniku-set skip, a następnie określonego rekordu. Wydaje mi się to dość zbędne (nie mówię, że to właśnie robi ta metoda, tylko zgaduję, że bazuje na nazwie zmiennej).

Teraz przełączyłem się na myBatis 3 dla następnej wersji mojej aplikacji. Moje pytanie brzmi: czy jest jakiś lepszy sposób na obsługę dużej ilości danych kawałek po kawałku w myBatis? Czy jest i tak aby mybatis przetwarzał pierwsze N rekordów, zwracał je do wywołujący, zachowując wynik ustawia połączenie otwarte, aby następnym razem użytkownik wywołał getList(...) zacznie czytać z rekordu N + 1 bez "pomijania"?

Author: Community, 2011-07-01

4 answers

Nie, mybatis nie ma jeszcze pełnej możliwości przesyłania strumieniowego wyników .

EDIT 1: Jeśli nie potrzebujesz zagnieżdżonych mapowań wyników, możesz zaimplementować niestandardowy moduł obsługi wyników do przesyłania strumieniowego wyników. na aktualnie wydanych wersjach MyBatis. (3.1.1) obecne ograniczenie dotyczy sytuacji, gdy trzeba wykonać złożone mapowanie wyników. NestedResultSetHandler nie pozwala na obsługę niestandardowych wyników. Poprawka jest dostępna i wygląda na to, że jest obecnie ukierunkowana na 3.2. Zobacz Wydanie 577.

Podsumowując, do przesyłania strumieniowego dużych zestawów wyników za pomocą MyBatis potrzebujesz.

  1. zaimplementuj własne wyniki .
  2. Zwiększ rozmiar pobierania. (jak zauważył poniżej Guillaume Perrot)
  3. dla zagnieżdżonych map wyników, użyj poprawki omówionej w Issue 577 . Ta poprawka rozwiązuje również niektóre problemy z pamięcią przy dużych zestawach wyników.
 7
Author: Andy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-20 03:48:46

MyBatis może przesyłać strumieniowo wyniki. Potrzebujesz niestandardowego programu obsługi wyników. Dzięki temu możesz wziąć każdy wiersz osobno i zapisać go do pliku XML. Ogólny schemat wygląda tak:

session.select(
    "mappedStatementThatFindsYourObjects",
    parametersForStatement,
    resultHandler);

Gdzie resultHandler jest instancją klasy implementującej interfejs ResultHandler. Interfejs ten ma tylko jedną metodę handleResult. Ta metoda udostępnia obiekt ResultContext. Z tego kontekstu można pobrać aktualnie czytany wiersz i coś z nim zrobić.

handleResult(ResultContext context) {
  Object result = context.getResultObject();
  doSomething(result);
}
 16
Author: Stefan Oehme,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-29 03:33:38

HandleResult otrzymuje tyle rekordów, ile pobiera zapytanie, bez pauzy.

Gdy jest zbyt wiele rekordów do przetworzenia użyłem sqlSessionFactory.getSession ().getConnection (). Następnie jako normalny JDBC, pobieramy instrukcję, pobieramy Resultset i przetwarzamy po kolei rekordy. Nie zapomnij zamknąć sesji.

 2
Author: user3806853,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-05 02:08:16

Jeśli po prostu wysyp wszystkie dane bez wymogu zamawiania z tabel, dlaczego nie bezpośrednio zrobić paginacji w SQL? Ustawia limit instrukcji query, gdzie określa inny identyfikator rekordu jako offset, aby oddzielić całą tabelę na kawałki, z których każdy może być bezpośrednio wczytany do pamięci, jeśli limit wierszy jest rozsądną liczbą.

SQL może być coś w stylu:

SELECT * FROM resource 
    WHERE "ID" >= continuation_id LIMIT 300;

Myślę, że to może być postrzegane jako alternatywne rozwiązanie do zrzucenia wszystkich danych przez kawałki, pozbycie się różnych problemów z funkcjami w mybatis, lub dowolnej warstwie trwałości, wsparcie.

 0
Author: 千木郷,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-24 13:23:56