Java JPA CriteriaBuilder-如何向标准添加具有不同动态类型的参数?获取不明确的调用错误
我是JPA的新手,遇到了一个相当直截了当的用例。我所要做的就是根据特定的过滤器用户传递到我的应用程序,在我的条件中添加一些条件。用户使用键、值对将信息传递给应用程序,我们将对其进行解码以查看每个参数的类型 例如: 1) key=id,value=20。我们将其解释为按id=20进行搜索,其中id是整数 2) key=name和value='test'。我们将其解释为按name='test'搜索,其中name是string 这是通过这样的方法实现的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
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子句中限制的列的名称,可以简单地对其进行调整(请参阅上面的第三个限制)