简体   繁体   English

JPA where where子句

[英]JPA where clause any

In JPA, the query is: 在JPA中,查询是:

Query q = entityManager.createQuery("select o from Product o WHERE o.category = :value");
q.setParameter("category", category);

How can I set category to any category in JPA? 如何在JPA中将类别设置为任何类别? So if the null category passed, I simple ignore the category parameter, select all products. 因此,如果传递null类,我简单地忽略category参数,选择所有产品。

How can I set category to any category in JPA? 如何在JPA中将类别设置为任何类别? So if the null category passed, I simple ignore the category parameter, select all products. 因此,如果传递null类,我简单地忽略category参数,选择所有产品。

You'll have to build the query dynamically here. 您必须在此动态构建查询。 With HQL (this is a simplified example): 使用HQL(这是一个简化的例子):

Map<String, Object> params = new HashMap<String, Object>();
StringBuffer hql = new StringBuffer("from Product p");
boolean first = true;

if (category != null) {
    hql.append(first ? " where " : " and ");
    hql.append("p.category = :category");
    params.put("category", category);
}

// And so on...

Query query = session.createQuery(hql.toString());

Iterator<String> iter = params.keySet().iterator();
while (iter.hasNext()) {
    String name = iter.next();
    Object value = params.get(name);
    query.setParameter(name, value);
}

List results = query.list()

But, actually, my recommendation would be to use the Criteria API here: 但实际上,我的建议是在这里使用Criteria API:

Criteria criteria = session.createCriteria(Product.class);
if (category != null) {
    criteria.add(Expression.eq("category", category);
}
// And so on...
List results = criteria.list();

Much simpler for complicated dynamic queries. 复杂的动态查询更简单。

要归档参数变为可选,您可以编写查询而无需使用Criteria API:

select o from Product o WHERE :value is null or :value='' or o.category = :value

You are right almost with small change. 你几乎是小改变。

Query query = entityManager.createQuery("select o from Product o WHERE o.category = :value");
query.setParameter("value", category);

in setParamater "value" (exact text) should match with ":value" in query. 在setParamater中, “value” (确切文本)应与查询中的“:value”匹配。

How can I set category to any category in JPA? 如何在JPA中将类别设置为任何类别? So if the null category passed, I simple ignore the category parameter, select all products. 因此,如果传递null类,我简单地忽略category参数,选择所有产品。

You can set the category to "%". 您可以将类别设置为“%”。 if (category == null) query.setParameter("category", "%"); if(category == null)query.setParameter(“category”,“%”); else query.setParameter("category", category); else query.setParameter(“category”,category);

SELECT * FROM PRODUCT WHERE CATEGORY=* SELECT * FROM PRODUCT WHERE CATEGORY = *

I think you are new to SQL, too. 我认为你也是SQL新手。

WHERE CATEGORY = * does not mean "any category" (it is not even valid SQL). WHERE CATEGORY = *并不意味着“任何类别”(它甚至不是有效的SQL)。

In both SQL and JPA, you would just not have the WHERE clause at all if you want any category (or in SQL you could have WHERE CATEGORY IS NOT NULL ). 在SQL和JPA中,如果你想要任何类别(或者在SQL中你可以拥有WHERE CATEGORY IS NOT NULL ),你根本就没有WHERE子句。

Pascal Thivent gave pretty good answer recommending using Criteria . Pascal Thivent给出了很好的答案,推荐使用Criteria However the Criteria in his answer is pure Hibernate criteria. 然而,他的答案中的Criteria是纯粹的Hibernate标准。 Using JPA Criteria example: 使用JPA Criteria示例:

private List<Result> getProduct(String category) {
    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    CriteriaQuery<Product> criteria = builder.createQuery(Product.class);
    Root<Product> productRoot = criteria.from(Product.class);

    if (category != null)
        criteria.where(builder.equal(productRoot.get("category"), category))    
    }

    entityManager.createQuery(criteria).getResultList();
}

The thing you are trying to achieve is counter intuitive in terms of design pattern. 你试图实现的东西在设计模式方面是反直觉的。 Let's think of the problems in SQL terms ignoring all JPA and other. 让我们想一想SQL术语中忽略所有JPA和其他问题的问题。

The corresponding SQL query of your JPQL looks like below 您的JPQL的相应SQL查询如下所示

SELECT o.* FROM product o WHERE o.category = 'SOME_CAT';

Now if you pass null instead of category SOME_CAT the SQL would be like 现在,如果您传递null而不是类别SOME_CAT那么SQL就像

SELECT o.* FROM product o WHERE o.category IS NULL;

There is no SQL standard to invert the result set altering param value unless your SQL looks like following 除非您的SQL看起来如下,否则没有SQL标准来反转结果集更改参数值

SELECT o.* FROM product o WHERE o.category IS NOT NULL;

The similar JPQL will look like 类似的JPQL看起来像

SELECT o FROM Product o WHERE o.category <> :param

You can see that we need to invert the logical operation instead of manipulating the param. 您可以看到我们需要反转逻辑操作而不是操纵参数。 There is no standard way to achive this behavior unless you build JPQL dynamically with if else condition. 除非使用if else条件动态构建JPQL,否则没有标准方法可以实现此行为。

I would prefer a separate method handler one for filtering with category and other for listing all regardless of category. 我更喜欢一个单独的方法处理程序,一个用于过滤类别,另一个用于列出所有类别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM