我创建了对象人,我可以删除并修改它,我也可以通过他的名字或电话搜索人 ...但我不知道例如,知道如何通过他的**家庭地址搜索一个人**。这是我的代码:
我的实体 Person.java :
public class Person{
private Long id;
private String name;
@ManyToOne(cascade = CascadeType.ALL)
private Address address;
....
}
我的实体 Address.java
public class Address{
...
private String streetName;
...
}
这是我试图修改以获得我想要的最有趣的功能,我想搜索居住在xxx(streetName = xxx)中的人。这是我的函数 getByQuery :
public List<Person> getByQuery(PersonSearchQuery searchQuery) {
Map<String, String> criteriaQuery = new HashMap<String, String>();
if (searchQuery.getName() != null)
criteriaQuery.put("name",searchQuery.getName());
TypedQuery<Person> query = this.findByQuery(criteriaQuery);
return query.getResultList();
}
对象 PersonSearchQuery 仅包含属性name(String)和streetName(String)及其getter。
功能 findByQuery :
public TypedQuery<T> findByQuery(Map<String, String> criteriaQuery) {
CriteriaBuilder builder = this.em.getCriteriaBuilder();
CriteriaQuery<T> criteria = builder.createQuery(this.entityClass);
Root<T> root = criteria.from(this.entityClass);
criteria.select(root);
Predicate predicate = builder.conjunction();
if (criteriaQuery.size() != 0) {
for (String key : criteriaQuery.keySet()) {
try{
predicate = builder.and(predicate, builder.equal(root.<String>get(key), criteriaQuery.get(key)));
}catch(IllegalArgumentException e){
continue;
}
}
}
criteria.where(predicate);
return this.em.createQuery(criteria);
}
所以我可以按名字搜索人员,我无法通过 streetName 搜索它们问题是我的功能 getByQuery 我想要做这样的事情:
if (searchQuery.getStreetName() != null)
criteriaQuery.put("Address.streetName",searchQuery.getStreetName());
问题是我不知道在这种情况下如何定义密钥。谢谢你的帮助
答案 0 :(得分:0)
如果我有几个类似的实体需要以相同的方式使用/呈现,我只使用CriteriaBuilder
,所以如果person是唯一具有Address引用的实体,我会使用JPQL,如下所示:< / p>
entityManager.createQuery(
"select p from Person p where p.address.streetName like :streetName", Person.class)
.setParameter("streetName", "xyz" + "%").getResultList()
我倾向于避免使用CriteriaBuilder的主要原因是因为它有一个相当陡峭的学习曲线,你需要编写很多代码来表达非常简单的概念。相比之下,任何熟悉SQL的开发人员都可以读取和维护JPQL代码。
这些天我总是使用框架,比如DeltaSpike Data(用于EE)和Spring Data,它们都实现了大部分基本的DAO / Repository功能,所以如果你不介意额外的依赖(和一些魔法)它可以为你节省很多样板JPA代码。