Java 有没有办法用JPA/hibernate滚动结果?

Java 有没有办法用JPA/hibernate滚动结果?,java,hibernate,orm,jpa,toplink,Java,Hibernate,Orm,Jpa,Toplink,我在Toplink中找到了一些提示 Query query = em.createQuery("SELECT e FROM Employee e ORDER BY e.lastName ASC, e.firstName ASC"); query.setHint("eclipselink.cursor.scrollable", true); ScrollableCursor scrollableCursor = (ScrollableCursor)query.getSingleResult();

我在Toplink中找到了一些提示

Query query = em.createQuery("SELECT e FROM Employee e ORDER BY e.lastName ASC, e.firstName ASC");
query.setHint("eclipselink.cursor.scrollable", true);
ScrollableCursor scrollableCursor = (ScrollableCursor)query.getSingleResult();
List<Employee> emps = scrollableCursor.next(10);
Query Query=em.createQuery(“通过e.lastName ASC、e.firstName ASC从员工e订单中选择e”);
setHint(“eclipseelink.cursor.scrollable”,true);
ScrollableCursor ScrollableCursor=(ScrollableCursor)query.getSingleResult();
List emps=scrollableCursor.next(10);

有jpa/hibernate的替代方案吗?

据我所知,jpa中没有标准

对于Hibernate,我所知道的最接近的替代方法是
查询
/API。从文件中:

如果您的JDBC驱动程序支持 可滚动的结果集,查询 接口可用于获取 ScrollableResults对象,该对象允许 查询的灵活导航 结果

Query q = sess.createQuery("select cat.name, cat from DomesticCat cat " +
                            "order by cat.name");
ScrollableResults cats = q.scroll();
if ( cats.first() ) {

    // find the first name on each page of an alphabetical list of cats by name
    firstNamesOfPages = new ArrayList();
    do {
        String name = cats.getString(0);
        firstNamesOfPages.add(name);
    }
    while ( cats.scroll(PAGE_SIZE) );

    // Now get the first page of cats
    pageOfCats = new ArrayList();    
    cats.beforeFirst();    
    int i=0;    
    while( ( PAGE_SIZE > i++ ) && cats.next() ) pageOfCats.add( cats.get(1) );

}

cats.close()
请注意,一个开放的数据库连接 这需要光标 功能。使用
setMaxResult()
/
setFirstResult()
如果 需要脱机分页功能


在JPA中,您可以使用query.setFirstResult和query.setMaxResults,也可以使用Spring数据。在这里,您可以指定查询并作为参数传递“PageRequest”,其中您可以指示页面大小和页码:

Page<User> users = repository.findAll(new PageRequest(1, 20));
Page users=repository.findAll(新的页面请求(1,20));
为此,您需要扩展分页和排序存储库

这是另一种翻页搜索结果的方法

Query q = sess.createQuery("select cat.name, cat from DomesticCat cat " +
                            "order by cat.name");
ScrollableResults cats = q.scroll();
if ( cats.first() ) {

    // find the first name on each page of an alphabetical list of cats by name
    firstNamesOfPages = new ArrayList();
    do {
        String name = cats.getString(0);
        firstNamesOfPages.add(name);
    }
    while ( cats.scroll(PAGE_SIZE) );

    // Now get the first page of cats
    pageOfCats = new ArrayList();    
    cats.beforeFirst();    
    int i=0;    
    while( ( PAGE_SIZE > i++ ) && cats.next() ) pageOfCats.add( cats.get(1) );

}

cats.close()

当然,在底层,它使用Hibernate、Toplink或任何您配置的JPA实现。

当基于
列表
实例处理大型项目代码中的大量实体时, 我必须编写一个非常有限的列表实现,只支持
迭代器
来浏览
可滚动结果
,而不必使用
列表
重构所有服务实现和方法原型

此实现在我的

它还定期从会话中刷新Hibernate实体。下面是一种使用它的方法,例如,当使用
for
循环将所有未归档的实体从数据库导出为文本文件时:

Criteria criteria = getCurrentSession().createCriteria(LargeVolumeEntity.class);
criteria.add(Restrictions.eq("archived", Boolean.FALSE));
criteria.setReadOnly(true);
criteria.setCacheable(false);
List<E> result = new IterableListScrollableResults<E>(getCurrentSession(),
        criteria.scroll(ScrollMode.FORWARD_ONLY));
for(E entity : result) {
    dumpEntity(file, entity);
}
Criteria=getCurrentSession().createCriteria(LargeVolumeEntity.class);
添加(Restrictions.eq(“归档”,Boolean.FALSE));
条件。setReadOnly(true);
条件。可设置缓存(false);
列表结果=新的IterableListScrollableResults(getCurrentSession(),
criteria.scroll(仅限ScrollMode.FORWARD_));
对于(E实体:结果){
转储实体(文件、实体);
}

希望它能有所帮助

从其他答案来看,JPA不支持直接滚动,但如果您使用Hibernate作为JPA实现,您可以这样做

javax.persistence.Query query = entityManager.createQuery("select foo from bar");
org.hibernate.Query hquery = query.unwrap(org.hibernate.Query);
ScrollableResults results = hquery.scroll(ScrollMode.FORWARD_ONLY);

它访问底层HibernateAPI进行滚动,但您可以使用JPA查询的所有功能。(至少对于条件查询,JPA api有一些旧Hibernate api中没有的功能。)

这不是滚动。每次启动一个新查询时,开销都会增加。另外,您需要对可靠的分页进行排序,这也会增加查询时间。不幸的是,这似乎是获得类似于滚动的功能(如果不是性能的话)的唯一方法。如果要“滚动”在线添加/删除数据的实时数据库,并且在页面边界附近添加/删除数据,您还可以跳过或翻倍一些记录……别忘了关闭()尝试。。。最后