首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带有多个参数的JPA Criteria API

带有多个参数的JPA Criteria API
EN

Stack Overflow用户
提问于 2012-08-30 22:39:18
回答 5查看 101.1K关注 0票数 39

我需要创建一个使用带有多个参数的JPA Criteria API的搜索方法。现在的问题是,并不是每个参数都是必需的。所以有些可能是空的,它们不应该包含在查询中。我已经在CriteriaBuilder上尝试过了,但我不知道如何让它工作。

有了Hibernate Criteria API,这就相当简单了。只需创建条件,然后添加限制。

代码语言:javascript
运行
复制
Criteria criteria = session.createCriteria(someClass.class);
if(someClass.getName() != null) {
   criteria.add(Restrictions.like("name", someClass.getName());
}

如何使用JPA的Criteria API实现相同的功能?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-08-30 23:04:46

概念是构造javax.persistence.Predicate数组,它只包含我们想要使用的谓词:

要查询的实体示例:

代码语言:javascript
运行
复制
@Entity
public class A {
    @Id private Long id;    
    String someAttribute;
    String someOtherAttribute;
    ...
}

查询本身:

代码语言:javascript
运行
复制
    //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();
票数 94
EN

Stack Overflow用户

发布于 2012-08-30 22:50:21

看看这个网站的JPA Criteria API。有很多例子。

更新:提供一个具体的示例

让我们搜索余额低于特定值的账户:

代码语言:javascript
运行
复制
SELECT a FROM Account a WHERE a.balance < :value

首先创建一个Criteria Builder

代码语言:javascript
运行
复制
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));

要获取结果集,请设置参数并运行查询:

代码语言:javascript
运行
复制
TypedQuery<Account> query = entityManager.createQuery(accountQuery);
query.setParameter(value, 1234.5);
List<Account> results = query.getResultList();

顺便说一句: entityManager被注入到EJB/服务/DAO中的某个位置。

票数 7
EN

Stack Overflow用户

发布于 2019-07-21 04:38:23

Spring的一个简单解决方案,使用lambda表达式:

代码语言:javascript
运行
复制
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);
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12199433

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档