【问题标题】:Select entities that have a field with occurence different from using spring jpa选择具有与使用 spring jpa 不同的字段的实体
【发布时间】:2020-06-11 13:22:22
【问题描述】:

我有一个名为证书的实体

@Entity
public class CertificateData {
    @Id private String id;
    private long expireDate;
    private long createDate;
    private int status;
    private String subjectDN;
...
}

许多证书可以具有相同的主题,我想选择所有主题 ID 字段计数不同于 3 的证书。我使用了此代码并且它有效

public List<CertificateData> findAllByRedundancy() {
    Map<String, Integer> subjectDNCount = new HashMap<>();
    Map<String, List<CertificateData>> subjectDNCertificates = new HashMap<>();

    List<CertificateDto> certificateDataList =
       this.certificaterepository
       .findAll().forEach(certificateData -> {
          String subject = certificateData.getSubjectDN();
          if(subjectDNCount.containsKey(subject)){
              subjectDNCount.put(subject, subjectDNCount.get(subject)+1);
              subjectDNCertificates.get(subject).add(certificateData);
          }
          else{
              subjectDNCount.put(subject, 1);
              subjectDNCertificates.put(subject, new ArrayList<>());
              subjectDNCertificates.get(subject).add(certificateData);
         }
  });
  List<CertificateDto> result = new ArrayList<>();
  subjectDNCount.forEach((s, i) -> {
     if(i!=3){
        result.addAll(subjectDNCertificates.get(s));
  }
  });

  return result;
}

我尝试使用带有查询注释的 Spring JPA 来做同样的事情,如下所示:

@Query("select c from CertificateData c group by c.subjectDN Having count(c) <> 3")
List<CertificateData> findAllByRedundancy();

但它不会返回所有证书。它只返回不同主题DN的证书。

【问题讨论】:

    标签: java spring-boot spring-data-jpa jpql


    【解决方案1】:

    您的注释中的查询似乎选择了组而不是 CertificateData 记录。获取CertificateData 记录本身的一种方法是使用子查询来查找所需的subjectDN 值(这是您已经拥有的),然后让外部查询找到具有这些subjectDN 值的记录.我还没有对此进行测试,但在 JPQL 中会是这样的:

    @Query(
            "select c from CertificateData c where c.subjectDN in " +
            "(" +
            "   select c.subjectDN from CertificateData c " +
            "   group by c.subjectDN having count(c) <> 3" +
            ")"
    )
    List<CertificateData> findAllByRedundancy();
    

    作为参考,执行此操作的 SQL(特别是 postgres)类似于:

    select * from certificate_data where subject_dn in 
    (
        select subject_dn from certificate_data 
        group by subject_dn having count(*) <> 3
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-20
      • 2015-01-11
      • 1970-01-01
      • 2020-04-23
      • 2016-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多