mok*_*ril 32 java jpa criteria-api
我需要创建一个使用带有多个参数的JPA Criteria API的搜索方法.现在的问题是不是每个参数都是必需的.因此有些可能为null,并且它们不应包含在查询中.我已经用CriteriaBuilder尝试了这个,但我看不出如何让它工作.
使用Hibernate Criteria API,这非常简单.只需创建条件,然后添加限制.
Criteria criteria = session.createCriteria(someClass.class);
if(someClass.getName() != null) {
criteria.add(Restrictions.like("name", someClass.getName());
}
Run Code Online (Sandbox Code Playgroud)
我怎么能用JPA的Criteria API实现同样的目标?
Mik*_*unu 81
概念是构造javax.persistence.Predicate数组,它只包含我们想要使用的谓词:
要查询的示例实体:
@Entity
public class A {
@Id private Long id;
String someAttribute;
String someOtherAttribute;
...
}
Run Code Online (Sandbox Code Playgroud)
查询本身:
//some parameters to your method
String param1 = "1";
String paramNull = null;
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery cq = qb.createQuery();
Root<A> customer = cq.from(A.class);
//Constructing list of parameters
List<Predicate> predicates = new ArrayList<Predicate>();
//Adding predicates in case of parameter not being null
if (param1 != null) {
predicates.add(
qb.equal(customer.get("someAttribute"), param1));
}
if (paramNull != null) {
predicates.add(
qb.equal(customer.get("someOtherAttribute"), paramNull));
}
//query itself
cq.select(customer)
.where(predicates.toArray(new Predicate[]{}));
//execute query and do something with result
em.createQuery(cq).getResultList();
Run Code Online (Sandbox Code Playgroud)
Spring 的一个简单解决方案,使用 lambda 表达式:
Specification<User> specification = (root, query, builder) -> {
List<Predicate> predicates = new ArrayList<>();
// like
predicates.add(builder.like(root.get("name"), "%test%"));
// equal
predicates.add(builder.equal(root.get("parent_id"), 99L);
// AND all predicates
return builder.and(predicates.toArray(new Predicate[0]));
};
repository.findAll(specification);
Run Code Online (Sandbox Code Playgroud)
看看这个网站JPA Criteria API.有很多例子.
更新:提供一个具体的例子
让我们搜索余额低于特定值的帐户:
SELECT a FROM Account a WHERE a.balance < :value
Run Code Online (Sandbox Code Playgroud)
首先创建一个Criteria Builder
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Account> accountQuery = builder.createQuery(Account.class);
Root<Account> accountRoot = accountQuery.from(Account.class);
ParameterExpression<Double> value = builder.parameter(Double.class);
accountQuery.select(accountRoot).where(builder.lt(accountRoot.get("balance"), value));
Run Code Online (Sandbox Code Playgroud)
要获取结果集参数并运行查询:
TypedQuery<Account> query = entityManager.createQuery(accountQuery);
query.setParameter(value, 1234.5);
List<Account> results = query.getResultList();
Run Code Online (Sandbox Code Playgroud)
BTW:entityManager被注入EJB/Service/DAO中的某个地方.
| 归档时间: |
|
| 查看次数: |
77165 次 |
| 最近记录: |