在批量检索和Criteria.ROOT_ENTITY中优化OneToMany FetchType.Edge

时间:2012-07-19 02:56:00

标签: java hibernate

我有一个用户要求,要求我在数据树表中列出一组数据。

数据集包括一对多字段。

示例:产品具有名称,类型和多种颜色。

所以他们的颜色存储在另一个表中(一对多关系)

用户希望数据表列出产品并将颜色包含为字段之一

示例:红色,绿色,蓝色,黄色(按颜色分隔)

这是一项非常成本的操作,因为它涉及加入,因此如果有1000个产品,则需要很长时间才能加载。

OOT问题。

对于Criteria,我使用list函数。我设置了ResultTransformer(Criteria.ROOT_ENTITY)和setMaxResult(5000)。

根据我的理解,这将检索5000条记录,对其进行结果转换

但这意味着我最后会列出不到5000条记录。

我如何确保分钟。 5000条记录?

例如

Criteria crit = getCriteria(Product.clas)
crit.setMaxResult(5000)
crit.ResultTransformer(Criteria.DISTINCT_ROOT_ENTITY )

1 个答案:

答案 0 :(得分:1)

  1. 如果您想要删除Join中的重复行(包括FetchType.eager),则需要使用

    Criteria.DISTINCT_ROOT_ENTITY 
    NOT
    Criteria.ROOT_ENTITY
    使用Criteria.ROOT_ENTITY,每行结果都是根实体的实例。

  2. 在大多数情况下,我更喜欢使用两个独立的查询。

  3. 第一个查询只有条件有Criteria.DISTINCT_ROOT_ENTITY并返回PK值。

    第二个查询从第一个查询的结果中按PK选择具有分页或最大大小限制的结果。

    // First Query
    Criteria ct1 = createCriteria(Product.class)
        .add( Restrictions.eq("blah", val) )
        .setProjection(Projections.id());
        .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
    List<Integer> pks = ct1.list();
    
    // Second Query
    Criteria ct2 = createCriteria(Product.class)
        .add( Restrictions.in("id", pks) )
        .setFirstResult(000)
        .setMaxResult(000)
    return ct2.list();
    

    重要的问题是我们不能直接在第一个查询中应用分页。因为在Criteria.DISTINCT_ROOT_ENTITY之前应用了分页选项setMaxResult或setFirstResult。所以,我们需要第二次查询。