Java JPA CriteriaBuilder-如何向标准添加具有不同动态类型的参数?获取不明确的调用错误

Java JPA CriteriaBuilder-如何向标准添加具有不同动态类型的参数?获取不明确的调用错误,java,jpa,spring-data-jpa,criteria-api,jpa-2.1,Java,Jpa,Spring Data Jpa,Criteria Api,Jpa 2.1,我是JPA的新手,遇到了一个相当直截了当的用例。我所要做的就是根据特定的过滤器用户传递到我的应用程序,在我的条件中添加一些条件。用户使用键、值对将信息传递给应用程序,我们将对其进行解码以查看每个参数的类型 例如: 1) key=id,value=20。我们将其解释为按id=20进行搜索,其中id是整数 2) key=name和value='test'。我们将其解释为按name='test'搜索,其中name是string 这是通过这样的方法实现的 public <T> T getSe

我是JPA的新手,遇到了一个相当直截了当的用例。我所要做的就是根据特定的过滤器用户传递到我的应用程序,在我的条件中添加一些条件。用户使用键、值对将信息传递给应用程序,我们将对其进行解码以查看每个参数的类型

例如:

1) key=id,value=20。我们将其解释为按id=20进行搜索,其中id是整数

2) key=name和value='test'。我们将其解释为按name='test'搜索,其中name是string

这是通过这样的方法实现的

public <T> T getSearchValue(Object inputValue) {
   if (condition) {
      return (T) inputValue.toString();
   } else {
      return (T) Integer.parseInt(inputValue.toString);
   }
}
cb.equal(getSearchKey(), getSearchValue(inputValue));
cb.gt(getSearchKey(), getSearchValue(inputValue));
这里
cb.equal
工作正常。但是
cb.gt
或任何其他操作,如
lessThan
等,都会产生编译错误,即有2个方法匹配,因此不明确


第一种方法是
gt(Expression),其思想是为“SQL语句”的where子句提供限制

许多人喜欢编写类似于SQL的JPQL查询,因为阅读时更容易理解。然而,使用此Criteria API有一些优点(动态、不易出错、不太关注安全性、更容易重构)

第一步是获取
CriteriaBuilder
,然后用它创建一个
CriteriaQuery
。之后,您可以继续定义要从哪个类构建
根目录
,并使用它来获取列。接下来还可以进行连接

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<YourClass> cq = cb.createQuery(YourClass.class);
Root<YourClass>  root = cq.from(YourClass.class);
下面是这样一个DAO方法的完整示例

public List<Foo>(String state, int size, String column, String value) {
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<Foo> cq = cb.createQuery(Foo.class);
    Root<Foo>  root = cq.from(Foo.class);

    List<Predicate> predicates = new ArrayList<>();
    predicates.add(cb.equal(root.get(Foo_.bla), state));
    predicates.add(cb.gt(root.get(Foo_.blub), size));
    predicates.add(cb.equal(root.get(column), value));

    cq.select(root).where(cb.and(predicates.toArray(new Predicate[predicates.size()])));

    return entityManager.createQuery(cq).getResultList();
}
公共列表(字符串状态、整数大小、字符串列、字符串值){
CriteriaBuilder cb=entityManager.getCriteriaBuilder();
CriteriaQuery cq=cb.createQuery(Foo.class);
Root=cq.from(Foo.class);
列表谓词=新的ArrayList();
add(cb.equal(root.get(Foo_.bla),state));
add(cb.gt(root.get(Foo_.blub),size));
add(cb.equal(root.get(column),value));
select(root).where(cb.and(predicates.toArray)(新谓词[predicates.size()));
返回entityManager.createQuery(cq.getResultList();
}
为了获得列名(或单数属性),我使用了
hibernate jpamodelgen
。看看这个插件,它自动生成带有下划线的类(例如
Foo_u979;
),这使得使用列名时更安全


更新:如果您事先不知道where子句中限制的列名称,则可以简单地对其进行调整(请参见上面的第三个限制)。

想法是将限制提供给“SQL语句”的where子句

许多人喜欢编写类似于SQL的JPQL查询,因为阅读时更容易理解。然而,使用此Criteria API有一些优点(动态、不易出错、不太关注安全性、更容易重构)

第一步是获取
CriteriaBuilder
,然后用它创建一个
CriteriaQuery
。之后,您可以继续定义要从哪个类构建
根目录
,并使用它来获取列。接下来还可以进行连接

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<YourClass> cq = cb.createQuery(YourClass.class);
Root<YourClass>  root = cq.from(YourClass.class);
下面是这样一个DAO方法的完整示例

public List<Foo>(String state, int size, String column, String value) {
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<Foo> cq = cb.createQuery(Foo.class);
    Root<Foo>  root = cq.from(Foo.class);

    List<Predicate> predicates = new ArrayList<>();
    predicates.add(cb.equal(root.get(Foo_.bla), state));
    predicates.add(cb.gt(root.get(Foo_.blub), size));
    predicates.add(cb.equal(root.get(column), value));

    cq.select(root).where(cb.and(predicates.toArray(new Predicate[predicates.size()])));

    return entityManager.createQuery(cq).getResultList();
}
公共列表(字符串状态、整数大小、字符串列、字符串值){
CriteriaBuilder cb=entityManager.getCriteriaBuilder();
CriteriaQuery cq=cb.createQuery(Foo.class);
Root=cq.from(Foo.class);
列表谓词=新的ArrayList();
add(cb.equal(root.get(Foo_.bla),state));
add(cb.gt(root.get(Foo_.blub),size));
add(cb.equal(root.get(column),value));
select(root).where(cb.and(predicates.toArray)(新谓词[predicates.size()));
返回entityManager.createQuery(cq.getResultList();
}
为了获得列名(或单数属性),我使用了
hibernate jpamodelgen
。看看这个插件,它自动生成带有下划线的类(例如
Foo_u979;
),这使得使用列名时更安全

更新:如果您事先不知道where子句中限制的列的名称,可以简单地对其进行调整(请参阅上面的第三个限制)