如何在条件构建器中使用子字符串

时间:2018-09-03 10:56:16

标签: postgresql jpa spring-data-jpa substring criteria

我想将字符串11.0.3.200转换为0011.0000.0003.0200以便对该字符串降序进行排序。

Expression<String> majorVer = cb.function("SUBSTRING_INDEX", String.class, uf.get(sortAttr), cb.literal("."), cb.literal(1)); //11      
Expression<String> lpadMajorValue = cb.function("lpad", String.class, majorVer, cb.literal(4), cb.literal("0"));

Expression<String> minorVerBase = cb.function("REPLACE", String.class, uf.get(sortAttr), cb.concat(majorVer, cb.literal(".")), cb.literal(""));//0.3.200      
Expression<String> minorVer = cb.function("SUBSTRING_INDEX", String.class, minorVerBase, cb.literal("."), cb.literal(1)); //0
 Expression<String> lpadMinorValue = cb.function("lpad", String.class, minorVer, cb.literal(4), cb.literal("0"));

Expression<String> buildVerBase = cb.function("REPLACE", String.class, minorVerBase, cb.concat(minorVer, cb.literal(".")), cb.literal("")); //3.200
Expression<String> buildVer = cb.function("SUBSTRING_INDEX", String.class, buildVerBase, cb.literal("."), cb.literal(1)); //3
Expression<String> lpadBuildValue = cb.function("lpad", String.class, buildVer, cb.literal(4), cb.literal("0"));

Expression<String> revVer = cb.function("REPLACE", String.class, buildVerBase, cb.concat(buildVer, cb.literal(".")), cb.literal("")); //200
Expression<String> lpadRevisionValue = cb.function("lpad", String.class, revVer, cb.literal(4), cb.literal("0"));

Expression<String> lpadValue = cb.concat(lpadMajorValue, cb.concat(lpadMinorValue, cb.concat(lpadBuildValue, lpadRevisionValue)));

 orderList.add(cb.desc(lpadValue));

但是我遇到一个例外:

nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; 
nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
org.postgresql.util.PSQLException: ERROR: function substring_index(text) does not exist"

如果我将SUBSTRING_INDEX与标准构建一起使用时有问题,请提出任何建议。如果条件构建器不支持SUBSTRING_INDEX,那有什么选择?

1 个答案:

答案 0 :(得分:0)

JPA 2.2规范的第4.6.17.2节列出了JPA中可用的功能,但不包括SUBSTRING_INDEX。我想可以肯定地说,早期版本也不包含它。因此,JPA无法将其转换为特定于数据库的内容。

它也不是Postgres的SQL方言的一部分。因此,正如您所注意到的那样,简单的传递也不起作用。

幸运的是,JPA知道LOCATE听起来像您要找的东西。

根据规范:

  

LOCATE函数返回给定字符串在字符串中的位置,从指定位置开始搜索。它以整数形式返回找到字符串的第一个位置。第一个参数是要定位的字符串。第二个参数是要搜索的字符串;可选的第三个参数是一个整数,代表开始搜索的字符串位置(默认情况下,是要搜索的字符串的开头)。字符串中的第一个位置由1表示。如果找不到该字符串,则返回0。