Java JPA标准生成器:如何按顺序替换字符串并将其转换为数字?

Java JPA标准生成器:如何按顺序替换字符串并将其转换为数字?,java,jpa,spring-data-jpa,criteria,builder,Java,Jpa,Spring Data Jpa,Criteria,Builder,有人可以建议我如何使用JPA Criteria builder API构建以下查询吗 SELECT id, name, date, version FROM public.upgradeTable order by (CAST(replace(version, '.', '')AS numeric)) desc; 请注意,我们的“版本”列的值类似于“11.0.2.213”、“11.0.2.73” 我们需要在版本中修剪字符“.”,然后将它们转换为数字,然后按desc排序。目前JPA没有用于rep

有人可以建议我如何使用JPA Criteria builder API构建以下查询吗

SELECT id, name, date, version FROM public.upgradeTable
order by (CAST(replace(version, '.', '')AS numeric)) desc;
请注意,我们的“版本”列的值类似于“11.0.2.213”、“11.0.2.73”
我们需要在版本中修剪字符“.”,然后将它们转换为数字,然后按desc排序。

目前JPA没有用于replace()和cast(字符串为数字)的API。但是,如果数据库可移植性不重要,则可以使用CriteriaBuilder.function(…)创建数据库本机函数

对于MySQL,示例的order by表达式为:

    Expression<String> replacedValue = criteriaBuilder.function("replace", 
            String.class, root.get("version"), criteriaBuilder.literal("."), 
            criteriaBuilder.literal(""));

    Expression<String> lpadValue = criteriaBuilder.function("lpad", 
            String.class, replacedValue, criteriaBuilder.literal(20),
            criteriaBuilder.literal("0"));

    criteriaQuery.orderBy(criteriaBuilder.desc(lpadValue));
Expression replacedValue=criteriaBuilder.function(“replace”,
String.class、root.get(“版本”)、criteriaBuilder.literal(“.”),
criteriaBuilder.literal(“”);
表达式lpadValue=criteriaBuilder.function(“lpad”,
String.class,replacedValue,criteriaBuilder.literal(20),
criteriaBuilder.literal(“0”);
orderBy(criteriaBuilder.desc(lpadValue));
CriteriaBuilder.function(…)不支持本机函数,如
cast(值作为类型)或convert(值,类型)
。因此,使用lpad(…)可以获得相同的orderBy结果

它与一个轻量级的JPA实现非常配合,适用于Java和Android


免责声明:我是Cmobilecom JPA的开发人员。

首先,这是无效的JPQL,JPQL中没有“替换”函数(或标准)。第二,显示到目前为止您已经尝试了什么,以及您有什么问题的具体部分是的,我已经在那里搜索了,但没有在criteria builder内部替换。但我们的要求是对这个版本列进行排序。因为version列是varchar,所以它提供字符串排序。因此,当使用jpa时,我们使用orderList.add(cb.desc(uf.get(“version”))它根据字符串进行排序,并在“11.0.2.213”上方列出“11.0.2.73”。要解决这个问题,我们需要删除“从版本将其转换为数字,然后进行排序。描述中给出的查询正在运行…在实际的postgress数据库上,我们需要找到任何方法或其他方法在JPQL或java critera builder中实现此功能。请建议我在中解释的相同方法,因此这是该问题的重复。请不要提出dup问题。我将删除一个。但是,您能否建议是否有办法在criteria builder中处理此问题。嗨,John,谢谢您的回复,我的回复很有效。当我看到您的回复时,我已经了解了替换函数。但我无法了解如何实现lpad函数。再次感谢您宝贵的回复。嗨,John,您正确地提到CAST不可用但是使用lpad确实是非常好的建议,我们创建它是为了比较格式为“11.2.2000.3”或“11.2.2000.111”的版本。在这种情况下,总数为10的lpad工作正常。但是在比较“11.2.2000.3”和“4.200.10.10”时,它将失败最后,它会比较11220003和42001010。它会考虑“4.200。10。10”更大。因此,在替换“?”之后,Builder提供了任何函数或方法来将它转换成整数。请在标准API中有一种将字符串转换为整数的方法,将“11220003”和“42001010”转换成整数,“4.200.10.10”也会更大。如果我正确理解您的orderBy版本,您应该从第一部分开始逐部分比较它们。对于上面的示例,第一部分“11”大于“4”,以“11”开头的版本更大。在Criteria API中,有locate()和substring(),但提取4个部分可能会很复杂。Oracle有regexp_substr()。MySQL有substring_index()。您可能需要为数据库创建一个函数。MySQL substring_index()并不完全是从字符串中提取部分。但它可以用于lpad。