我使用JPA CriteriaBuilder从MySQL数据库中选择MyEntity
类型的实体,如下所示:
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 ) );
因此,查询结果应包含name
值与给定regExp匹配的任何实体。但结果列表始终为空。
将regExp更改为/(abc|def)/g
无效,也不会添加通配符%
如何使模式匹配起作用?
或者:我如何将本机MySQL REGEXP与CriteriaBuilder一起使用?
答案 0 :(得分:3)
JPA查询中的模式匹配仅限于
_
- 任何角色%
- 任意字符串 REGEXP
在MySQL中具有运算符语法(SELECT 'a' REGEXP 'A'
),因此无法与CriteriaBuilder.function()
API一起使用。我担心最好是运行本机SQL查询。
如果你正在使用Hibernate,你还有一个选择。您可以wrap REGEXP
operator in SQLFunctionTemplate
, extend hibernate dialect使用CriteriaBuilder.function()
运行。
答案 1 :(得分:1)
也许这段代码会有所帮助。我们必须在搜索中排除字符,我们使用Oracle。 CriteriaBuilder(至少从2.1开始)将允许您调用函数。
private static final Pattern UNDESIRABLES = Pattern.compile("[(){},.;!?<>%_-]");
private static final String UNDESIRABLE_REPLACEMENT = "";
...
在搜索方法中,创建要在where子句中使用的谓词:
Expression<String> undesirables = cb.literal(UNDESIRABLES.toString());
Expression<String> replaceWith = cb.literal(UNDESIRABLE_REPLACEMENT);
Expression<String> regExp = cb.function("REGEXP_REPLACE", String.class, client.get(Client_.companyName),
undesirables, replaceWith);
Predicate companyNameMatch = cb.equal(cb.trim(cb.lower(regExp)), removeUndesireables(name).trim());
...
为右手comapare创建一个使用与左边相同的值的方法:
private String removeUndesireables(String name) {
return UNDESIRABLES.matcher(name).replaceAll(UNDESIRABLE_REPLACEMENT).toLowerCase();
}
答案 2 :(得分:1)
我最近遇到过这个并使用第一篇文章来实现hibernate mysql函数选项。
为了帮助我节省一些时间,这就是我所做的:
在hibernate中设置自定义方言文件中的函数:
public class MySQLDialect extends Dialect {
public MySQLDialect() {
super();
...
registerFunction("regexp", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "?1 REGEXP ?2"));
...
}
...
}
然后 在标准构建器部分中:
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);
然后使用theRegexPredicate在CriteriaBuilder查询中构造where子句。