Я должен заставить свое веб-приложение работать с действительно огромными наборами данных. В данный момент я получаю или OutOfMemoryException или произвожу, который сгенерирован 1-2 минуты.
Давайте поместим его простой и предположим, что у нас есть 2 таблицы в DB: Worker
и WorkLog
приблизительно с 1 000 строк в первой и 10 000 000 строк во второй. Последняя таблица имеет несколько полей включая 'workerId' и 'hoursWorked' полей среди других. То, в чем мы нуждаемся:
рассчитайте общие часы работали каждым пользователем;
список периодов работы для каждого пользователя.
Самый простой подход (IMO) для каждой задачи в плоскости SQL:
1)
select Worker.name, sum(hoursWorked) from Worker, WorkLog
where Worker.id = WorkLog.workerId
group by Worker.name;
//results of this query should be transformed to Multimap<Worker, Long>
2)
select Worker.name, WorkLog.start, WorkLog.hoursWorked from Worker, WorkLog
where Worker.id = WorkLog.workerId;
//results of this query should be transformed to Multimap<Worker, Period>
//if it was JDBC then it would be vitally
//to set resultSet.setFetchSize (someSmallNumber), ~100
Так, у меня есть два вопроса:
предположим, что у нас есть 2 таблицы в БД: Worker и WorkLog с примерно 1000 строк в первой и 10 000 000 строк во второй
Для таких больших объемов я бы рекомендовал использовать интерфейс StatelessSession
из Hibernate:
В качестве альтернативы Hibernate предоставляет командно-ориентированный API, который можно использовать для потоковой передачи данных в базу данных и из нее базы данных в виде отделенных объектов. У
StatelessSession
нет никакого контекст персистентности, связанный с ним и не обеспечивает многие из семантики жизненного цикла более высокого уровня. В в частности, сессия без статического состояния не реализует кэш первого уровня и не не взаимодействует ни с кэшем второго уровня, ни с кэшем запросов. Он не реализует транзакционную запись-слежение или автоматической проверки на загрязнения. Операции выполняемые с помощью сеанса без статического состояния никогда не каскадируются на связанные экземпляры. Коллекции игнорируются сеансом без статического состояния сессией. Операции, выполняемые с помощью сеанс без статического состояния, обходят модель событий Hibernate модель событий и перехватчики. Из-за отсутствия кэша первого уровня, сессии без утверждения уязвимы к эффектам смешения данных. Сеанс без статических данных сеанс без статических данных - это абстракция более низкого уровня которая гораздо ближе к базовому JDBC.StatelessSession session = sessionFactory.openStatelessSession(); Транзакция tx = session.beginTransaction(); ScrollableResults customers = session.getNamedQuery("GetCustomers") .scroll(ScrollMode.FORWARD_ONLY); while (customers.next()) { Customer customer = (Customer) customers.get(0); customer.updateStuff(...); session.update(customer); } tx.commit(); session.close();
В этом примере кода,
Customer
экземпляры, возвращенные запросом немедленно отделяются. Они никогда не не ассоциируются ни с каким контекстом.Операции
insert(), update()
иdelete()
, определяемые операциямиStatelessSession
, считаются считаются прямыми операциями базы данных операции на уровне строки. Они приводят к немедленное выполнение SQLINSERT, UPDATE
илиDELETE
соответственно. Они имеют различную семантикой, чемsave(), saveOrUpdate()
иdelete()
операций, определенныхSession
интерфейс.