【问题标题】:How to translate this SQL (or similar) to Criteria JPA如何将此 SQL(或类似)转换为 Criteria JPA
【发布时间】:2020-11-19 14:38:58
【问题描述】:

我有这个 SQL,需要解析为 Criteria JPA。我读到我不能在 JPA 中使用 UNION,所以我需要一个类似的解决方案。

我有 3 个表(具有相同的字段),需要在数据表中联合打印。

查询是:

SELECT * FROM (
    SELECT id, project_id, start_date, end_date, 'cs' FROM construction_shares
    UNION
    SELECT id, project_id, start_date, end_date, 'ips' FROM intervention_pr_shares
    UNION
    SELECT id, project_id, start_date, end_date, 'is' FROM intervention_shares
) AS t ORDER BY START_DATE ASC;

有人可以帮我吗?

非常感谢!

【问题讨论】:

    标签: java mysql sql jpa criteria


    【解决方案1】:

    Criteria JPA 不支持 UNION,您可以尝试两种选择。

    1. 创建一个原生查询并从 entityManager 执行,结果是 POJOS 列表。
    2. 像这样抛出 3 个查询:

    SharesPojo:

    private Integer id;
    private Integer projectId;
    private Date startDate; 
    private Date endDate
    
    public SharesPojo(Integer id, Integer projectId, Date startDate, Date endDate);
    

    道:

    CriteriaBuilder cb = em.getCriteriaBuilder();
    
    CriteriaQuery<SharesPojo> csQuery = cb.createQuery(SharesPojo.class);
    Root<ConstructionShares> csRoot = csQuery.from(ConstructionShares.class);
    csQuery.multiselect(
        csRoot.get(ConstructionShares_.id)
        csRoot.get(ConstructionShares_.projectId)
        csRoot.get(ConstructionShares_.startDate)
        csRoot.get(ConstructionShares_.endDate)
    );
    
    CriteriaQuery<SharesPojo> ipsQuery = cb.createQuery(SharesPojo.class);
    Root<InterventionPrShares> ipsRoot = ipsQuery.from(InterventionPrShares.class);
    ipsQuery.multiselect(
        ipsRoot.get(InterventionPrShares_.id)
        ipsRoot.get(InterventionPrShares_.projectId)
        ipsRoot.get(InterventionPrShares_.startDate)
        ipsRoot.get(InterventionPrShares_.endDate)
    );
    
    CriteriaQuery<SharesPojo> isQuery = cb.createQuery(SharesPojo.class);
    Root<InterventionShares> isRoot = isQuery.from(InterventionShares.class);
    isQuery.multiselect(
        isRoot.get(InterventionShares_.id)
        isRoot.get(InterventionShares_.projectId)
        isRoot.get(InterventionShares_.startDate)
        isRoot.get(InterventionShares_.endDate)
    );
    
    List<SharesPojo> unionList = new ArrayList<>();
    unionList.addAll(em.createQuery(csQuery).getResultList());
    unionList.addAll(em.createQuery(ipsQuery).getResultList());
    unionList.addAll(em.createQuery(isQuery).getResultList());
    

    【讨论】:

    • Criteria 解决方案可以工作...但是如果我想按 startDate 排序并且只获得 10 个第一个结果,例如?
    • 实际上这是这个实现的一个问题。你仍然有原生选项。这也将是测试在没有过滤器的情况下进行完整搜索并使用来自 java 8 的流和 lambdas 过滤列表以获得前 10 个排序的性能。
    猜你喜欢
    • 1970-01-01
    • 2017-03-15
    • 1970-01-01
    • 2016-01-06
    • 2014-10-08
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 2016-01-12
    相关资源
    最近更新 更多