问题描述
Select c.id,(Select c2.value from customer_table c2 Where c2.id = c.id And c2.key = 'test') as "test",(Select c2.value from customer_table c2 Where c2.id = c.id And c2.key = 'service-category') as "service-category",(Select c2.value from customer_table c2 Where c2.id = c.id And c2.key = 'exam') as "exam"
From customer_table c
Group By c.id;
解决方法
假设customerTable实体的存在和正确的建模,其关系以及该值的类型为String,则实现应如下所示:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<YourPojo> cq = cb.createQuery(YourPojo.class);
Root<CustomerTable> root = cq.from(CustomerTable.class);
//Subquery 1
Subquery<String> sqVal1 = cq.subquery(String.class);
Root<CustomerTable> sq1Root = sqVal1.from(CustomerTable.class);
sqVal1.where(
cb.and(
cb.equal(root.get("id"),sq1Root.get("id")),cb.equal(sq1Root.get("key"),"test")
)
);
sqVal1.select(sq1Root.get("value"));
//Subquery 2
Subquery<String> sqVal2 = cq.subquery(String.class);
Root<CustomerTable> sq2Root = sqVal2.from(CustomerTable.class);
sqVal2.where(
cb.and(
cb.equal(root.get("id"),sq2Root.get("id")),cb.equal(sq2Root.get("key"),"service-category")
)
);
sqVal2.select(sq2Root.get("value"));
//Subquery 3
Subquery<String> sqVal3 = cq.subquery(String.class);
Root<CustomerTable> sq3Root = sqVal3.from(CustomerTable.class);
sqVal3.where(
cb.and(
cb.equal(root.get("id"),sq3Root.get("id")),cb.equal(sq3Root.get("key"),"exam")
)
);
sqVal3.select(sq3Root.get("value"));
cq.groupBy(root.get("id"));
cq.multiselect(
root.get("id"),sqVal1.getSelection(),sqVal2.getSelection(),sqVal3.getSelection()
);
您需要一个带有构造器的pojo,该构造器的参数(顺序和类型)与multiselect子句相同
public class YourPojo {
public YourPojo(String id,String val1,String val2,String val3){
[...]
}
}
建议使用元模型访问实体的属性,这将导致替换以下代码
root.get("id");
与其他人
root.get(CustomerTable_.id);
使用元模型而无需太深入主题的众多优势之一是能够自动完成属性名称并减少此时的出错机会。