Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jpa javaee中复杂对象属性的查询搜索_Jpa_Jakarta Ee - Fatal编程技术网

Jpa javaee中复杂对象属性的查询搜索

Jpa javaee中复杂对象属性的查询搜索,jpa,jakarta-ee,Jpa,Jakarta Ee,我已经创建了对象Person,我可以删除和修改它,还可以通过他的姓名或电话号码搜索Person。。。但我不知道如何通过**家庭地址**来搜索一个人。这是我的密码: 我的实体Person.java: public class Person{ private Long id; private String name; @ManyToOne(cascade = CascadeType.ALL) private Address address; .... } public List<Person

我已经创建了对象Person,我可以删除和修改它,还可以通过他的姓名或电话号码搜索Person。。。但我不知道如何通过**家庭地址**来搜索一个人。这是我的密码:

我的实体Person.java

public class Person{
private Long id;
private String name;
@ManyToOne(cascade = CascadeType.ALL)
private Address address;
....
}
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();
}
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);
}
我的实体地址.java

public class Address{
...
private String streetName;
...
}
这是我试图修改的最有趣的函数,我想搜索住在xxx(streetName=xxx)的人。这是我的函数getByQuery

public class Person{
private Long id;
private String name;
@ManyToOne(cascade = CascadeType.ALL)
private Address address;
....
}
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();
}
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);
}

问题是我不知道在这种情况下如何定义键。感谢您的帮助

如果我有几个类似的实体需要以相同的方式使用/呈现,我只会使用
CriteriaBuilder
,因此如果person是唯一具有地址引用的实体,我只会使用JPQL,如下所示:

if (searchQuery.getStreetName() != null)
        criteriaQuery.put("Address.streetName",searchQuery.getStreetName());
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/存储库功能,因此如果您不介意额外的依赖性(以及一些神奇的功能),它可以为您节省大量的JPA样板代码。

您可以从“根”连接到地址。然后可以得到Address对象的字段。那么您建议我更改函数findByQuery?但问题是,我想多次使用这个函数(分解),无论如何,我如何使用我的JOIN@neilstockton如果你需要访问非候选对象的字段,那么你需要加入。您可以通过查阅基本的JPA标准文档来使用连接,例如Thank@NeilStockton,现在它正在工作。我只想通过使用一个函数来概括所有情况,而不必为地址和每个复杂对象创建函数。我使用了许多实体@Klaus,这就是我使用CriteriaBuilder的原因。否则,我已经解决了我的问题,但通过创建一个包含大量对齐的函数来验证每个复杂对象(连接)。