在 JPA CriteriaBuilder 中使用正则表达式

jp-*_*jee 6 java regex mysql hibernate jpa

我正在使用 JPA CriteriaBuilderMyEntity从 MySQL 数据库中选择类型的实体,如下所示:

String regExp = "(abc|def)"
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery query = cb.createQuery( MyEntity.class );
root = query.from( MyEntity.class );
predicates = new ArrayList<Predicate>();

predicates.add( cb.like( root.<String>get( "name" ), regExp ) );
Run Code Online (Sandbox Code Playgroud)

因此,查询结果应包含name值与给定 regExp 匹配的任何实体。但结果列表始终为空。将 regExp 更改为/(abc|def)/g无效,添加通配符也无效%

如何使模式匹配工作?

或者:如何将本机 MySQL REGEXP 与 CriteriaBuilder 一起使用?

zbi*_*big 6

JPA 查询中的模式匹配仅限于

  • _ - 任何字符
  • % - 任何字符串

REGEXP在 MySQL ( SELECT 'a' REGEXP 'A') 中有运算符语法,因此它不能与CriteriaBuilder.function()API一起使用。恐怕最好的方法是运行本机 SQL 查询。

如果您正在使用 Hibernate,您还有一种选择。您可以REGEXP运算符包装在 中SQLFunctionTemplate,扩展休眠方言并使用CriteriaBuilder.function().


Sim*_*n B 5

我最近遇到了这个问题,并使用第一篇文章来实现 hibernate mysql 函数选项。

为了帮助其他人节省一些时间,我这样做了:

在休眠中的自定义方言文件中设置该函数:

public class MySQLDialect extends Dialect {

   public MySQLDialect() {
      super();
      ...
      registerFunction("regexp", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "?1 REGEXP ?2"));
      ...
   }
   ...
}
Run Code Online (Sandbox Code Playgroud)

然后在标准构建器部分中:

CriteriaBuilder builder = ...;    

Pattern regexPattern = Pattern.compile("^[0-9]\\|[0-9]+");

Expression<String> patternExpression = builder.<String>literal(regexPattern.pattern());

Path<String> path = ... ;// regex comparison column

// regexp comes from the name of the regex function 
// defined in the Mysql Dialect file above
Predicate theRegexPredicate = builder.equal(builder.function("regexp", Integer.class, path, patternExpression), 1);
Run Code Online (Sandbox Code Playgroud)

然后使用 RegexPredicate 在 CriteriaBuilder 查询中构造 where 子句。