在实体对象中获取聚合函数结果的最佳方法

时间:2015-11-18 11:29:39

标签: sql hibernate jpa aggregate-functions jpa-2.1

很多时候我必须在实体对象本身内获取SQL聚合查询结果。截至目前,我可以通过以下代码实现相同的目标

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Tuple> q = cb.createTupleQuery();
    Root<Test> c = q.from(Test.class);
    q.multiselect(c, cb.count(c));
    q.groupBy(c.get("type"));

    TypedQuery<Tuple> t = em.createQuery(q);
    List<Tuple> resultList = t.getResultList();
    List<Test> list = new ArrayList<>();

    for(Tuple tuple : resultList){
        Test te = (Test) tuple.get(0);
        te.setQuantity((long)tuple.get(1));
        list.add(te);
    }

但我想知道什么是最好的方法。我的测试实体是

@Entity
@Table(name = "test")
public class Test {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(name = "name")
    private String name;

    @Column(name = "type")
    private Integer type = 0;

    @Transient
    private long quantity;
}

1 个答案:

答案 0 :(得分:0)

如果您无法使用@Formula,那么我建议您在选择基础上创建一个基本数据库视图,并将其他实体映射到该视图。然后,您可以使用@OneToOne@SecondaryTable将其映射到现有实体。

这具有符合JPA标准的附加优势(即不使用Hibernate的@Formula @Formula),看起来像是:

@Entity
@Table(name = "test")
public class Test {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(name = "name")
    private String name;

    @Column(name = "type")
    private Integer type = 0;

    @OneToOne//or via secondary table
    private TestSummaryInfo summaryInfo;

    public long getQuantity(){
        return summaryInfo.getQuantity();
    }
}

映射到视图的摘要:

@Entity
@Table(name = "vw_test_summary")
public class TestSummaryInfo {
    @Id
    @Column(name = "id")
    private Integer id;

    @Column(name = "quantity")
    private Long quantity;
}