在 JPA CriteriaQuery 中使用 @Embeddable 实体
Using an @Embeddable entity in a JPA CriteriaQuery
假设我有以下示例实体 - 一个是 @Embeddable
,嵌入另一个 @Entity
:
@Embeddable
public class ContactInfoEntity {
@Column
private String phone;
@Column
private String zipCode;
}
@Entity
@Table(name = "EMPLOYEE")
public class EmployeeEntity {
@Id
@Column(name = "EMPLOYEE_ID")
private Long employeeId;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "phone",
column = @Column(name = "EMPLOYEE_PHONE")),
@AttributeOverride(name = "zipCode",
column = @Column(name = "EMPLOYEE_ZIP_CODE"))
})
private ContactInfoEntity employeeContactInfo;
}
由 openjpa-maven-plugin 生成的元模型 类 仅包含一个 employeeContactInfo
变量,不包含 @AttributeOverride
列。
现在假设我想这样做:
Select the EMPLOYEE_ID
and EMPLOYEE_PHONE
where the EMPLOYEE_ZIP_CODE
is equal to "123456"
如何将其创建为 CriteriaQuery
?
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<String> qDef = cb.createQuery(String.class);
Root<EmployeeEntity> e = qDef.from(EmployeeEntity.class);
qDef.select(e.get(EmployeeEntity_.employeeId),
e.get(????))
.where(cb.equal(e.get(????), "123456"));
return entityManager.createQuery(qDef).getResultList();
示例方法可能如下所示:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Object[]> qDef = cb.createQuery(Object[].class);
Root<EmployeeEntity> e = qDef.from(EmployeeEntity.class);
qDef.multiselect(
e.get(EmployeeEntity_.employeeId),
e.get(EmployeeEntity_.employeeContactInfo).get(ContactInfoEntity_.phone));
qDef.where(
cb.equal(
e.get(EmployeeEntity_.employeeContactInfo).get(ContactInfoEntity_.zipCode),
cb.literal("123456")));
List<Object[]> objects = em.createQuery(qDef).getResultList();
for (Object[] element : objects) {
System.out.format("%d %s", element[0], element[1]);
}
根据您的喜好,您可能还希望获得如下查询结果:
构造函数表达式
public class EmployeeEntityResult {
private int id;
private String phone;
public EmployeeEntityResult(int id, String phone) {
this.id = id;
this.phone = phone;
}
...
}
CriteriaQuery<EmployeeEntityResult> cq = cb.createQuery(EmployeeEntityResult.class);
...
List<EmployeeEntityResult> result = em.createQuery(cq).getResultList();
for (EmployeeEntityResult element : result) {
System.out.format("%d %s", element.getId(), element.getPhone());
}
元组
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
...
cq.select(
cb.tuple(
e.get(EmployeeEntity_.employeeId)
.alias("id"),
e.get(EmployeeEntity_.employeeContactInfo).get(ContactInfoEntity_.phone)
.alias("phone")));
...
List<Tuple> tuple = em.createQuery(cq).getResultList();
for (Tuple element : tuple) {
System.out.format("%d %s", element.get("id"), element.get("phone"));
}
JPQL 查询如下所示:
SELECT e.id, e.employeeContactInfo.phone
FROM EmployeeEntity e
WHERE e.employeeContactInfo.zipCode = '123456'
假设我有以下示例实体 - 一个是 @Embeddable
,嵌入另一个 @Entity
:
@Embeddable
public class ContactInfoEntity {
@Column
private String phone;
@Column
private String zipCode;
}
@Entity
@Table(name = "EMPLOYEE")
public class EmployeeEntity {
@Id
@Column(name = "EMPLOYEE_ID")
private Long employeeId;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "phone",
column = @Column(name = "EMPLOYEE_PHONE")),
@AttributeOverride(name = "zipCode",
column = @Column(name = "EMPLOYEE_ZIP_CODE"))
})
private ContactInfoEntity employeeContactInfo;
}
由 openjpa-maven-plugin 生成的元模型 类 仅包含一个 employeeContactInfo
变量,不包含 @AttributeOverride
列。
现在假设我想这样做:
Select the
EMPLOYEE_ID
andEMPLOYEE_PHONE
where theEMPLOYEE_ZIP_CODE
is equal to "123456"
如何将其创建为 CriteriaQuery
?
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<String> qDef = cb.createQuery(String.class);
Root<EmployeeEntity> e = qDef.from(EmployeeEntity.class);
qDef.select(e.get(EmployeeEntity_.employeeId),
e.get(????))
.where(cb.equal(e.get(????), "123456"));
return entityManager.createQuery(qDef).getResultList();
示例方法可能如下所示:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Object[]> qDef = cb.createQuery(Object[].class);
Root<EmployeeEntity> e = qDef.from(EmployeeEntity.class);
qDef.multiselect(
e.get(EmployeeEntity_.employeeId),
e.get(EmployeeEntity_.employeeContactInfo).get(ContactInfoEntity_.phone));
qDef.where(
cb.equal(
e.get(EmployeeEntity_.employeeContactInfo).get(ContactInfoEntity_.zipCode),
cb.literal("123456")));
List<Object[]> objects = em.createQuery(qDef).getResultList();
for (Object[] element : objects) {
System.out.format("%d %s", element[0], element[1]);
}
根据您的喜好,您可能还希望获得如下查询结果:
构造函数表达式
public class EmployeeEntityResult { private int id; private String phone; public EmployeeEntityResult(int id, String phone) { this.id = id; this.phone = phone; } ... }
CriteriaQuery<EmployeeEntityResult> cq = cb.createQuery(EmployeeEntityResult.class); ... List<EmployeeEntityResult> result = em.createQuery(cq).getResultList(); for (EmployeeEntityResult element : result) { System.out.format("%d %s", element.getId(), element.getPhone()); }
元组
CriteriaQuery<Tuple> cq = cb.createTupleQuery(); ... cq.select( cb.tuple( e.get(EmployeeEntity_.employeeId) .alias("id"), e.get(EmployeeEntity_.employeeContactInfo).get(ContactInfoEntity_.phone) .alias("phone"))); ... List<Tuple> tuple = em.createQuery(cq).getResultList(); for (Tuple element : tuple) { System.out.format("%d %s", element.get("id"), element.get("phone")); }
JPQL 查询如下所示:
SELECT e.id, e.employeeContactInfo.phone
FROM EmployeeEntity e
WHERE e.employeeContactInfo.zipCode = '123456'