13

tôi cần phải chuyển đổi một truy vấn tiêu chí Hibernate như sauSử dụng dự báo trong JPA 2

curList = session.createCriteria(Islem.class) 
        .createAlias("workingDay", "d") 
        .setProjection(Projections.sum("amount")) 
        .add(Restrictions.eq("currency", CURRENCY)) 
        .add(Restrictions.eq("product", product)) 
        .add(Restrictions.ne("status", INACTIVE)) 
        .add(Restrictions.eq("d.status", ACTIVE)) 
        .getResultList(); 

Tuy nhiên, trong JPA (2) Tôi không có ý tưởng làm thế nào để thực hiện các dự - trong trường hợp này - tổng. Đó là lẻ rằng Hibernate và JPA (thậm chí Hibernate JPA 2) có sự khác biệt to lớn này đặc biệt là trong các truy vấn tiêu chí.

Tôi bắt đầu bằng cách

CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<Islem> cq = cb.createQuery(Islem.class); 
Root<Islem> isr = cq.from(Islem.class); 
cq.select(isr).where(cb.equal(isr.get("currency"), CURRENCY), 
        cb.notEqual(isr.get("status"), INACTIVE), 
        cb.equal(isr.get("product"), product)); 

tuy nhiên không có ý tưởng làm thế nào để thực hiện các dự báo đây không phải bí danh

Trả lời

24

Đó là một câu hỏi cũ, nhưng chúng ta hãy đưa ra một ví dụ:

Với CriteriaBuilder, không giống như Hibernate, bạn luôn bắt đầu với loại của kết quả bạn muốn truy vấn và sau đó xây dựng phép chiếu.

CriteriaBuilder cb = em.getCriteriaBuilder(); 
//We want Integer result 
CriteriaQuery<Integer> cq = cb.createQuery(Integer.class); 

//The root does not need to match the type of the result of the query! 
Root<Islem> isr = cq.from(Islem.class); 

//Create a join to access the variable status of working day 
Join<Islem,WorkingDay> join = isr.join("workingDay",JoinType.INNER); 

//Create the sum expression 
Expression<Integer> sum = cb.sum(isr.get("amount")); 

cq.where(
     cb.equal(isr.get("currency"), CURRENCY), 
     cb.notEqual(isr.get("status"), INACTIVE), 
     cb.equal(isr.get("product"), product), 
     cb.equal(join.get("status"), ACTIVE) 
).select(sum); 

Mặt khác nếu bạn muốn truy vấn cho các giá trị "lượng" thực tế, bạn có thể làm:

CompoundSelection<Integer> projection = cb.construct(Integer.class, cb.sum(isr.get("amount"))); 

cq.where(..).select(projection); 

List<Integer> amounts = em.createQuery(cq).getResultList(); 
+0

+1 Cuối cùng thích hợp ví dụ tổng! – icl7126

Các vấn đề liên quan