代码之家  ›  专栏  ›  技术社区  ›  yura

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

  •  9
  • yura  · 技术社区  · 14 年前

    我在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);
    

    有jpa/hibernate的替代方案吗?

    5 回复  |  直到 13 年前
        1
  •  12
  •   Pascal Thivent    14 年前

    据我所知,在JPA中没有这方面的标准。

    有了Hibernate,我知道最接近的选择是 Query / ScrollableResults 原料药。从文档中:

    10.4.1.6. Scrollable iteration

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

    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() 如果你 需要脱机分页功能。

        2
  •  5
  •   JanKanis    7 年前

    从其他答案来看,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);
    

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

        3
  •  4
  •   Yves Martin    10 年前

    当处理大型项目代码中的大量实体时,基于 List<E> 实例, 我必须写一个非常有限的列表实现 Iterator 支持浏览 ScrollableResults 不需要重构所有的服务实现和方法原型 列表<E> .

    此实现可在我的 IterableListScrollableResults.java Gist

    它还定期刷新会话中的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);
    }
    

    希望能有所帮助

        4
  •  1
  •   frandevel    11 年前

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

    Page<User> users = repository.findAll(new PageRequest(1, 20));
    

    为此,您需要扩展分页和排序存储库。

    就像另一种翻页结果的方法一样。

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

        5
  •  0
  •   Pau    14 年前

    在JPA中,可以使用query.setFirstResult和query.setMaxResults

    推荐文章