【问题标题】:Build a search query with a search criteria in another table using JPA criteria使用 JPA 条件在另一个表中使用搜索条件构建搜索查询
【发布时间】:2013-05-14 08:42:13
【问题描述】:

我需要根据Country 表中的给定国家名称(不是countryId)从StateTable 中搜索州,该表应使用JPA 标准API 匹配like SQL 运算符(countryId 顾名思义就是StateTable 中的外键)。

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<StateTable> criteriaQuery = criteriaBuilder
                                          .createQuery(StateTable.class);
Root<StateTable>root=criteriaQuery.from(StateTable.class);

List<Predicate>predicates=new ArrayList<Predicate>();

predicates.add(criteriaBuilder
          .like(root.<String>get("countryName"), "%"+countryName+"%"));

criteriaQuery.where(predicates.toArray(new Predicate[0]));

entityManager.createQuery(criteriaQuery)
             .setFirstResult(first)
             .setMaxResults(pageSize)
             .getResultList();

如何修改以下语句以满足需要? (同样countryName 在Country 表中可用,此条件查询是关于StateTable)。

predicates.add(criteriaBuilder
          .like(root.<String>get("countryName"), "%"+countryName+"%"));

使用 JPQL 很繁琐,因为需要为多个搜索条件构建查询。这只是一个演示/说明。


Country 实体:

@Entity
public class Country implements Serializable {
    @Id
    private Long countryId;             //<----------------------
    @Column(name = "country_name")
    private String countryName;
    @Column(name = "country_code")
    private String countryCode;
    @OneToMany(mappedBy = "countryId", fetch = FetchType.LAZY)
    private Set<StateTable> stateTableSet;
}

StateTable 实体:

@Entity
public class StateTable implements Serializable {
    @Id
    private Long stateId;
    @Column(name = "state_name")
    private String stateName;
    @JoinColumn(name = "country_id", referencedColumnName = "country_id")
    @ManyToOne(fetch = FetchType.LAZY)
    private Country countryId;                //<-------------------------------
}

【问题讨论】:

  • 你是如何定义Country和StateTable的关系的?无论如何,该解决方案似乎需要加入(使用 JPQL 和 Criteria API)
  • 是的,他们俩都有关系。 StateTable 有一个外键引用 Country 的主键。
  • 为了给出正确的答案,有必要知道 JPA 中的关系是如何定义的。请编辑您的问题并添加此信息
  • 编辑添加实体类。

标签: jpa criteria-api


【解决方案1】:

您需要执行连接:

Join<StateTable, Country> country = root.join("countryId");
predicates.add(criteriaBuilder.like(country.<String>get("countryName"), "%"+countryName+"%"));

【讨论】:

  • 我在两者之间引用了this 答案,它使用了一个子查询,但我无法理解它,因为我使用标准 API 的频率很低(实际上我必须对此进行更多研究) .通常,我使用 JPQL 或(HQL with Hibernate),但在这里几乎必须使用标准 API。你的答案有效。谢谢!
【解决方案2】:

您可以扩展您的标准定义,例如(假设 State 实体中有一个属性 country - 换句话说,假设您在 state 表中有 country_id 作为外键):

Join<StateTable, Country> country = root.join("country", JoinType.LEFT);

// and change predicate with 
predicates.add(cb.like(country.<String>get("countryName"), "%"+countryName+"%"));

这应该完成所有工作。

【讨论】:

  • 在 like() 方法上存在语法错误 - cannot find symbol symbol: method like(Path&lt;String&gt;,String) location: variable country of type Join&lt;StateTable,Country&gt;。
  • 是criteriaBuilder.like(...)
  • 使用criteriaBuilder.like(...),完全未使用连接 - Join&lt;StateTable, Country&gt; country = root.join("country", JoinType.LEFT); 引发异常 - java.lang.IllegalArgumentException: Unable to resolve attribute [countryName] against path。
  • 我只需要将root 替换为country,但我自己无法解决,抱歉。
猜你喜欢
  • 2020-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-22
  • 2021-10-31
相关资源
最近更新 更多