【问题标题】:how to write this query using jpa criteria api?如何使用 jpa 标准 api 编写此查询?
【发布时间】:2020-12-16 21:21:33
【问题描述】:
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;

【问题讨论】:

    标签: java spring-boot hibernate jpa criteria-api


    【解决方案1】:

    假设 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

    public class YourPojo {
        public YourPojo(String id, String val1, String val2, String val3){
           [...]
        }
    }
    

    建议使用元模型来访问实体的属性,这将导致替换以下代码

    root.get("id");
    

    与其他人

    root.get(CustomerTable_.id);
    

    在不深入主题的情况下使用元模型的众多优点之一是能够自动完成属性名称并减少此时出错的机会。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-21
      • 2012-09-25
      • 1970-01-01
      • 1970-01-01
      • 2011-08-01
      • 2011-03-22
      • 2011-11-12
      • 2012-11-28
      相关资源
      最近更新 更多