Select 个字段的出现次数不同于使用 spring jpa 的实体
Select entities that have a field with occurence different from using spring jpa
我有一个名为证书的实体
@Entity
public class CertificateData {
@Id private String id;
private long expireDate;
private long createDate;
private int status;
private String subjectDN;
...
}
许多证书可以有相同的主题,我想 select 所有 subjectId 字段计数不同于 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();
但它并不是 return 所有的证书。它 return 只有不同主题 DN 的证书。
您注释中的查询似乎是选择组而不是 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
)
我有一个名为证书的实体
@Entity
public class CertificateData {
@Id private String id;
private long expireDate;
private long createDate;
private int status;
private String subjectDN;
...
}
许多证书可以有相同的主题,我想 select 所有 subjectId 字段计数不同于 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();
但它并不是 return 所有的证书。它 return 只有不同主题 DN 的证书。
您注释中的查询似乎是选择组而不是 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
)