假设我有一个这样的查询对象:
final SQLQuery query = createQuery(); // org.hibernate.SQLQuery
// HibernateTransaction is just a wrapper around Hibernate's Transaction, Session and
// SessionFactory classes
// the corresponding method:
private SQLQuery createQuery(HibernateTransaction t) {
final SQLQuery query = t.fullSQLQuery(MY_QUERY_STRING);
query.addScalar("column1", Hibernate.LONG);
query.addScalar("column2", Hibernate.LONG);
query.setResultTransformer(new AliasToBeanResultTransformer(MyDTO.class));
return query;
}
SQLQuery
对象有一个名为iterate()
的方法。我的问题是,如果我尝试做这样的事情:
Iterator<MyDTO> iterator = query.iterate();
while(iterator.hasNext()) {
MyDTO dto = iterator.next();
// ...
}
我得到一个不支持迭代的异常。如果我使用query.list()
方法然后我得到一个List<MyDTO>
这很好但是如果我的查询返回一百万行它会变慢并最终耗尽内存。
我的问题是,使用Hibernate只能一次获取一行并且懒洋洋地迭代它们的惯用方法是什么?在我的例子中,我尝试逐行处理表中的数据。
我正在考虑使用聚簇索引,只查询1000行一次,接下来的1000将基于前1000个的最后一个id(所以我基本上考虑的是分页)但是我们使用的是MyISAM表而不是支持这个。
答案 0 :(得分:0)
您可以使用SQLQuery类中的setMaxResults()
和setFirstResult()
方法。它们允许您模拟offset
和limit
SQL子句。
例如,如果您希望将rownum = 0的结果加载到rownum = 50,则可以使用setFirstResult(0)
和setMaxResults(50)
等等。
答案 1 :(得分:0)
是的,我们可以使用setMaxResults()
的{{1}}和setFirstResult()
方法实现分页,你必须编写类似
org.hibernate.SQLQuery
和循环如下
// the corresponding method:
private SQLQuery createQuery(HibernateTransaction t,int lowLimit,int pageSize) {
final SQLQuery query = t.fullSQLQuery(MY_QUERY_STRING);
query.addScalar("column1", Hibernate.LONG);
query.addScalar("column2", Hibernate.LONG);
query.setFirstResult(lowLimit);
query.setMaxResults(pageSize);
query.setResultTransformer(new AliasToBeanResultTransformer(MyDTO.class));
return query;
}
所以这个循环将首先获取10条记录,然后将计数器递增10,这个循环将继续,直到所有记录都没有被提取,因为我不确定结果,因为我没有测试过这段代码但应该工作...