【问题标题】:JPA query - how to mix arbitrary query strings and CriteriaBuilderJPA 查询 - 如何混合任意查询字符串和 CriteriaBuilder
【发布时间】:2012-05-14 08:01:45
【问题描述】:

我需要查询表单

SELECT dontcare FROM Bar b WHERE x = y AND expr
  • x 是 Bar 中任意字段的名称,y 是特定值。这些是通过 Servlet 提供的,不能被信任。
  • expr 是一个特定于项目的过滤器,用于更改涉及其他字段的查询范围 - 这是受信任的,来自配置文件,可能非常复杂。

一种不安全的方法是

String qStr = "SELECT foo FROM Bar b WHERE " + x " = " + y " AND " + expr

但是 x 和 y 不是受信任的来源,因此容易受到注入攻击。我找到了 CriteriaBuilder,并对“x = y”部分进行了编程构建,该部分运行良好,但找不到如何附加“AND expr”。

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaBuilder<Bar> q = cb.createQuery(Foo.class);
Root<Bar> root = q.from(Bar.class);
Predicate p1 = cb.equals(root.get(x), y);
Predicate p2 = <====== help needed here, how can I use expr
q.where(cb.and(p1, p2));
Query query = em.createQuery(q);

有什么想法吗?我花了很多时间浏览教程和关于表达式、谓词、查询等的 javadocs。

【问题讨论】:

    标签: java jpa jpql


    【解决方案1】:

    使用条件 api,您可以创建连词,其中包含许多必须为真的谓词。

    如果你想要 OR,你可以使用析取。

    类似:

    Criteria crit = session.createCriteria(Product.class);
    Conjunction conjunction = Restrictions.conjunction();
    conjunction.add(Restrictions.isNull("location"));
    conjunction.add(Restrictions.eq("location", ""));
    crit.add(conjunction);
    

    【讨论】:

    • 这是一个休眠而不是 JPA 的东西吗?我找不到类 Restrictions 或 Conjunction...
    • 是的,你是对的,但我的印象是 JPA 类似;查看这两个链接了解更多信息:objectdb.com/java/jpa/query/jpql/logicalobjectdb.com/api/java/jpa/criteria/CriteriaBuilder 显然 CriteriaBuilder 有方法 combine() 和 disjunction()
    • 我认为你可以使用 CriteriaBuilder 中的方法和(谓词...限制)和或(谓词...限制)
    • 谢谢,我已经检查过了,但仍然找不到将“bz = 1 AND (bf =2 OR bf = 3)”之类的字符串转换为可用于CriteriaBuilder ...
    • 欧基,我想我现在明白你的问题了。我认为您可以通过使用 javax.persistence.Query 和方法 setParameter(java.lang.String name, java.lang.Object value); 来做你想做的事情,而不是仅仅将字符串粘贴在一起或使用 Criteria api。制作查询字符串,附加您配置的表达式,然后从查询的第一部分设置参数。使用 CriteriaBuilder,我认为您无法为所欲为。
    猜你喜欢
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 2021-05-24
    • 2014-03-28
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    相关资源
    最近更新 更多