2008-11-16 2 views
6

У меня есть большое количество строк в базе данных, из которых мне нужно создать XML-документ. Я использую hibernate 3. Основной метод list() в интерфейсах Criteria и Query выглядит опасным: я очень жалею, что он должен читать все записи в памяти, даже если я только перебираю их. Или есть какая-то ленивая магия загрузки? Если нет, у меня, похоже, осталось два варианта: использование прокрутки() или итерации() из Query (прокрутка также присутствует в критериях). итерация не выглядит так здорово, если я хочу иметь минимальные обратные SQL-запросы: «Первый SQL-запрос возвращает только идентификаторы». Так ли я прав, мне нужно использовать scroll() для этого?Спящий режим: избегать чтения всех записей в память сразу

+0

Этот материал применим и к NHibernate :) – 2008-11-16 18:02:09

ответ

1

Используйте метод setMaxResults() по критериям.

Criteria crit = sess.createCriteria(Cat.class); 
crit.setMaxResults(maxResults); 
crit.setFirstResult(firstResultIndex); 
List cats = crit.list(); 

http://hibernate.org/hib_docs/v3/reference/en/html/querycriteria.html

http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Criteria.html

+0

Что я хочу сделать, так это получить все результаты в транзакционном режиме. Полагаю, вы имеете в виду, что я должен собрать целый набор результатов из частей. Могу ли я использовать их для того, чтобы «сшить» мои последовательные большие результаты вместе, чтобы я действительно получил моментальный снимок с определенного момента времени. – auramo 2008-11-16 19:16:23

+0

Я не уверен, что вы подразумеваете под «получить все результаты в транзакционном режиме». – 2008-11-16 19:23:54

0

Это то, что я планирую делать: Создать временную таблицу с идентификаторами объектов всех строк мне нужно экспортировать:

Insert into BatchTable (ID, Seq) Select (O.ID, Sequence.Next) 
From MyObject O Where ... 

В небольших единицах рабочей нагрузки в объектах :

Select Min(B.Seq), Max(B.Seq) From BatchTable; 

for (batch = minBatch; batch <= maxBatch; batch += size) { 
beginTransaction(); 
results = query("Select O From MyObject O, BatchTable B 
        Where O.ID = B.ID and (? <= B.Seq AND B.Seq < ?)"); 

exportXML(results); 
for (MyObject O : results) { 
    O.setProcessed(True); 
    O.update(); 
} 
commit(); 
} 
1

Если вам не нужно, чтобы пометить объекты прочь, как procesed, вы можете просто использовать свиток() и выселить объекты из сессии, как вы сделали с ними.

2

Попытка с помощью прокрутки() в сочетании с этим:

http://docs.jboss.org/hibernate/core/3.3/api/org/hibernate/StatelessSession.html

ИПП командно-ориентированных для выполнения массовых операций с базой данных.

Сеанс без учета состояния не реализует кеш первого уровня и не взаимодействует с кешем второго уровня, а также не выполняет транзакционную запись или автоматическую грязную проверку, а также не выполняет операции с каскадом для связанных экземпляров. Сеансы игнорируются сеансом без сохранения. Операции, выполняемые с помощью сеанса сеанса без учета состояния бездействия Hibernate и перехватчиков. Сеансы без учета состояния уязвимы для эффектов сглаживания данных из-за отсутствия кеша первого уровня.

Для определенных видов транзакций сеанс без сохранения состояния может выполнять несколько быстрее, чем сеанс с состоянием.

Смежные вопросы