Spring JPA 标准构建器大于:我可以传递字符串值以比较数据库中的数字类型吗
Posted
技术标签:
【中文标题】Spring JPA 标准构建器大于:我可以传递字符串值以比较数据库中的数字类型吗【英文标题】:Spring JPA criteria builder greaterThan : Can I pass String value for comparing Number type in database 【发布时间】:2021-12-21 04:45:30 【问题描述】:我正在使用 Spring Data JPA 标准构建器 greaterThan
API 进行比较。
数据库字段rating
的类型为NUMBER(5,0)
。实体类有一个rating
类型为Integer
的字段。我正在传递String
类型的值进行比较。
即使我没有传递Integer
值进行比较,它仍然返回有效结果。请帮助我了解这是怎么可能的。
是不是说,当数据库中字段的实际数据类型是不同类型时,我可以将数据库字段的javaString
版本传递给greaterThan方法。
我的比较代码块看起来像这样
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery();
Root<Customer> root = cq.from(Customer.class);
//you can see here , value 20 I am passing as String
Predicate comparisonPredicate = cb.greaterThan(root.get("rating"), "20");
cq.where(comparisonPredicate );
cq.select(root);
TypedQuery<Customer> query = entityManager.createQuery(cq);
【问题讨论】:
在过程中的某个时刻(在 Java 或 Oracle SQL 引擎中),将尝试将值从字符串转换为数字的隐式转换。你可以直接在Oracle中使用SELECT * FROM DUAL WHERE 1 < '2'
db<>fiddle试试。
谢谢,如果在 Spring Data JPA 中发生这种情况,任何指向此转换的文档
【参考方案1】:
这种行为是not documented。 查看the openJPA source code for Expressions.GreaterThan,更具体地说是toKernelExpression,
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, CriteriaQueryImpl<?> q)
Value val1 = Expressions.toValue(e1, factory, q);
Value val2 = Expressions.toValue(e2, factory, q);
Expressions.setImplicitTypes(val1, val2, e1.getJavaType(), q);
return factory.greaterThan(val1, val2);
JPA 使用第一个表达式的类型来构建查询。 这种行为看起来是一个意外的功能,而不是有意的实现。你应该不依赖这个并且应该明确地转换变量。您还可以使用MetaModel 在尝试将苹果与橙子进行比较时出现编译器错误。
【讨论】:
以上是关于Spring JPA 标准构建器大于:我可以传递字符串值以比较数据库中的数字类型吗的主要内容,如果未能解决你的问题,请参考以下文章
构建RESTful服务(使用Spring Data JPA)