通过查询搜索Java EE中复杂对象的属性

时间:2017-05-29 10:00:27

标签: jpa java-ee

我创建了对象,我可以删除并修改它,我也可以通过他的名字或电话搜索 ...但我不知道例如,知道如何通过他的**家庭地址搜索一个人**。这是我的代码:

我的实体 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());

问题是我不知道在这种情况下如何定义密钥。谢谢你的帮助

1 个答案:

答案 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代码。