Само задаването на размера на извличане не е правилният подход. javadoc на Statement#setFetchSize()
вече посочва следното:
Дава на JDBC драйвера подсказка относно броя на редовете, които трябва да бъдат извлечени от базата данни
Драйверът всъщност е свободен да приложи или да игнорира намека. Някои драйвери го игнорират, някои драйвери го прилагат директно, някои драйвери се нуждаят от повече параметри. MySQL JDBC драйверът попада в последната категория. Ако проверите MySQL JDBC драйвер документация , ще видите следната информация (превъртете около 2/3 надолу до заглавката ResultSet ):
За да активирате тази функционалност, трябва да създадете екземпляр на Statement по следния начин:
stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE);
Моля, прочетете цялото раздел на документа, той описва и предупрежденията на този подход. Ето подходящ цитат:
Има някои предупреждения при този подход. Ще трябва да прочетете всички редове в набора от резултати (или да го затворите), преди да можете да зададете каквито и да било други заявки за връзката, или ще бъде изведено изключение.
(...)
Ако изявлението е в обхвата на транзакция, тогава заключванията се освобождават, когато транзакцията завърши (което предполага, че изявлението трябва да завърши първо). Както при повечето други бази данни, операторите не са завършени, докато не бъдат прочетени всички чакащи резултати в оператора или не се затвори активният набор от резултати за оператора.
Ако това не коригира OutOfMemoryError
(не Exception
), тогава проблемът вероятно е, че съхранявате всички данни в паметта на Java, вместо да ги обработвате незабавно веднага щом данните постъпят. Това ще изисква повече промени във вашия код, може би пълно пренаписване. Отговорих на подобен въпрос преди тук .