Jakarta ee 获取集合大小的标准API
我有两个实体: 第一人称表人称Jakarta ee 获取集合大小的标准API,jakarta-ee,jpa,criteria-api,Jakarta Ee,Jpa,Criteria Api,我有两个实体: 第一人称表人称 @Entity public class Person implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Integer id; @Column(name = "name", nullable = false, leng
@Entity
public class Person implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Integer id;
@Column(name = "name", nullable = false, length = 2147483647)
private String name;
@Column(name = "first_name", nullable = false, length = 2147483647)
private String firstName;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "peopleId")
private List<PeopleEmail> peopleEmailList;
//... constuctors
//... getters setters
}
正如您所看到的,这两个实体都处于一对多关系中。
我想创建另一个类:
public class PersonAndCompany{
private String personName;
private String companyName;
private int emailCount;
//... constuctors
//... getters setters
}
我想写一个typequery,用人名和公司名填充PersonAndCompany.class字段,另一个类和电子邮件数,其中个人电子邮件数超过2。我想使用标准api。我写了一些代码,但我不知道如何在PersonAndCompany.class中添加条件where和填充emailcount
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<PersonAndCompany> cq = cb.createQuery(PersonAndCompany.class);
Root<Person> person = cq.from(Person.class);
Join<Person, Company> company = person.join(Person_.companyId);
cq.where(cb.greaterThan(cb.size(person.get(Person_.peopleEmailList)), 2));
Selection<PersonAndCompany> select = cb.construct(PersonAndCompany.class,
person.get(Person_.firstName),
company.get(Company_.name));
cq.select(select);
TypedQuery<PersonAndCompany> query = em.createQuery(cq);
return query.getResultList();
我认为在select子句中为一些JPA提供和一些数据库包含一个子查询是可能的
Select p.firstName, c.name, (select count(e) from Email e where e.person = p) from Peron p join p.company c where size(p.emails) > 2
否则,您将需要使用计数和某种分组方式。where子句中的大小检查可以移动到having子句中
在JPQL中,它类似于,标准是等价的
Select p.id, p.firstName, c.name, count(e) from Peron p join p.company c join p.peopleEmaiList e group by p.id, p.firstName, c.name having count(e) > 2
您也可以读取对象,然后用Java获取集合的大小。您可以对电子邮件和公司使用联接或批取来避免n+1查询。当我想将派生值或计算值转换到不同的结构时,我更喜欢TupleQueries,如下所示:
CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
// add cq.from and joins
// add cq.where predicates
cq.select( cb.tuple(
person.get(Person_.firstName).alias("person"),
company.get(Company_.name).alias("company"),
// and maybe ...
cb.size(person.get(Person_.peopleEmailList)).alias("emailcount") );
// ...
...
TypedQuery<Tuple> typedQuery = getEntityManager().createQuery(cq);
for(Tuple t : typedQuery.getResultList()) {
PersonAndCompany ret = new PersonAndCompany();
ret.setPersonName( t.get("person", String.class) );
ret.setCompanyName( t.get("company", String.class) );
ret.setEmailCount( t.get("emailcount", Integer.class) );
}
return ret;
希望有帮助。祝你好运
CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
// add cq.from and joins
// add cq.where predicates
cq.select( cb.tuple(
person.get(Person_.firstName).alias("person"),
company.get(Company_.name).alias("company"),
// and maybe ...
cb.size(person.get(Person_.peopleEmailList)).alias("emailcount") );
// ...
...
TypedQuery<Tuple> typedQuery = getEntityManager().createQuery(cq);
for(Tuple t : typedQuery.getResultList()) {
PersonAndCompany ret = new PersonAndCompany();
ret.setPersonName( t.get("person", String.class) );
ret.setCompanyName( t.get("company", String.class) );
ret.setEmailCount( t.get("emailcount", Integer.class) );
}
return ret;