【问题标题】:How to form a JPA query?如何形成 JPA 查询?
【发布时间】:2016-03-29 11:33:43
【问题描述】:

我有下表:

我想用以下规则形成一个查询: 获取 type 不是 type1 和 type2 且 Flavor 不是 flavor1 的 product1。

类型可以是 type1、type 2 或 null。

我的查询是这样形成的:

    CriteriaBuilder cb = this.getEntityManager().getCriteriaBuilder();
    CriteriaQuery<Product> searchQuery = cb.createQuery(Product.class);
    Root<Product> u = searchQuery.from(Product.class);

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

    predicates.add(cb.and(cb.equal(u.get("product"),"product1"),cb.isNull(u.get("type")),cb.notEqual(u.get("flavor"), "flavor1")));

问题是这个查询什么也没返回……我错过了什么吗? 请注意,我的问题是指逻辑而不是语法,因为语法是通过形成返回一些虚拟结果的更简单查询来检查的。 谢谢!

【问题讨论】:

  • 相关实体的映射(可能是ProductService 映射)。此外,如果您的“where 子句”的基础是 AND,则将谓词添加到您的 predicates 而不包含在 AND 中。

标签: java mysql jpa predicates


【解决方案1】:

尝试删除顶级 AND 谓词。将每个谓词添加到 predicates 并从中创建 where

predicates.add(cb.equal(u.get("product"),"product1"))
predicates.add(cb.isNull(u.get("type")));
predicates.add(cb.notEqual(u.get("flavor"), "flavor1")); // and so on

然后

searchQuery.where(predicates.toArray(new Predicate[predicates.size()]));

最重要的是,请确保您的数据库内容与您的查询匹配,因此确实应该返回一些内容:)

正如我在你的“表格”中看到的,“类型”列中没有空值。数据库中此列中是否有任何空值?也许它在数据库中不为空,只有空字符串(这是一个很大的区别)

【讨论】:

  • 感谢您的回复,但我对其他产品(product2 等)也有规定,因此此解决方案不会有预期的结果 :(
  • 好吧,我只能参考您向我们展示的内容。您必须显示所有谓词。此外,您是否在您的数据库环境中以 sql 形式测试了您的查询?您可以尝试代理数据库调用以检查实际生成的 SQL 并进行调查。我提到的 NULL 值呢?
  • 误报!我将查询结果显示在一个表中,但我没有注意到所需的行在那里。还是谢谢!
  • 呵呵呵呵,失败了:) 祝你好运!
【解决方案2】:

看起来很简单。我认为您缺少的是数据库列中的 NULL 不匹配任何内容,除非您准确指定它。换句话说,如果您说type not in ('type1', 'type2'),您不会隐式获取空列。如果你想要它们,你必须要求它们:

使用 JPQL 查询:

List<User> c1 = em.createQuery("select u from User u where (type not in ('type1', 'type2') or type = null) and flavor != 'flavor1'", User.class).getResultList();
System.out.println(c1);

使用 CriteriaQuery:

// and with CriteriaQuery
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> q = cb.createQuery(User.class);
Root<User> u = q.from(User.class);
List<String> typeFilter = Arrays.asList("type1", "type2");
String flavor = "flavor1";
List<User> rs = em.createQuery(q.select(u).where( cb.or(cb.not(u.get("type").in(typeFilter)), cb.isNull(u.get("type"))), cb.notEqual(u.get("flavor"), flavor) ) ).getResultList();

这给了我以下输出:

Hibernate: select user0_.id as id1_0_, user0_.flavor as flavor2_0_, user0_.product as product3_0_, user0_.type as type4_0_ from User user0_ where (user0_.type not in  ('type1' , 'type2') or user0_.type is null) and user0_.flavor<>'flavor1'
[model.User@30263191]
Hibernate: select user0_.id as id1_0_, user0_.flavor as flavor2_0_, user0_.product as product3_0_, user0_.type as type4_0_ from User user0_ where (user0_.type not in  (? , ?) or user0_.type is null) and user0_.flavor<>?
[model.User@30263191]

有用的链接:How to query a column which value is null in JPA?.

【讨论】:

    猜你喜欢
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2012-12-30
    • 2021-11-19
    • 2014-01-15
    相关资源
    最近更新 更多