我使用oracle 10g
和hibernate 3.3.2
。 我在SQL中使用正则表达式之前,现在对于我第一次使用它的HQL。
Query query = getSession().createQuery("From Company company
where company.id!=:companyId and
regexp_like(upper(rtrim(ltrim(company.num))), '^0*514619915$' )");
这是我的HQL,当我不运行它regex_like
它运行正常功能。 但我不能够与执行它regex_like
表达。
它说..
嵌套异常是org.hibernate.hql.ast.QuerySyntaxException:意想不到AST节点:(近线1,列66 .....
请帮帮忙,我该如何使用regex_like
在休眠本地查询? 或其他一些替代这样做。
其实,你可以不给REGEXP_LIKE的东西比较的结果除了在PL / SQL条件语句。
休眠似乎没有返回类型不接受自定义函数,因为你总是需要比较输出的东西,即:
REGEXP_LIKE('bananas', 'a', 'i') = 1
由于Oracle不允许你比较这函数的结果不了了之,我想出了使用条件的情况下的解决方案:
public class Oracle10gExtendedDialect extends Oracle10gDialect {
public Oracle10gExtendedDialect() {
super();
registerFunction(
"regexp_like", new SQLFunctionTemplate(StandardBasicTypes.BOOLEAN,
"(case when (regexp_like(?1, ?2, ?3)) then 1 else 0 end)")
);
}
}
而你的HQL应该是这样的:
REGEXP_LIKE('bananas', 'a', 'i') = 1
它会工作:)
您可以最肯定使用你(只要Hibernate是供应商和JPQL)希望与Hibernate的HQL任何类型的数据库特有的功能。 您只需告诉Hibernate那些功能。 在3.3的唯一选择是提供一个自定义的方言,并注册从方言的构造函数。 如果你看一看基方言类,你会看到很多的注册功能的示例。 平时最好延长您目前使用的确切的话,只需提供您的扩展(在这里,注册功能)。
一个有趣的注意的是,Oracle不归类为一个函数REGEXP_LIKE。 他们把它归类为条件/谓语。 我认为这主要是因为甲骨文的SQL不定义一个布尔数据类型,即使他们的PL / SQL不和我敢打赌REGEXP_LIKE被定义为PL / SQL函数返回布尔...
假设您目前使用Oracle10gDialect,你会怎么做:
public class MyOracle10gDialect extends Oracle10gDialect {
public Oracle10gDialect() {
super();
registerFunction(
"regexp_like",
new StandardSQLFunction( "regexp_like", StandardBasicTypes.BOOLEAN )
);
}
}
我不记得,如果在HQL解析器喜欢在所有的本身是一个谓语方面然而返回布尔函数。 有时,您可能要真/假转换成别的东西并核对收益:
public class MyOracle10gDialect extends Oracle10gDialect {
public Oracle10gDialect() {
super();
registerFunction(
"regexp_like",
new StandardSQLFunction( "regexp_like", StandardBasicTypes.INTEGER ) {
@Override
public String render(
Type firstArgumentType,
List arguments,
SessionFactoryImplementor factory) {
return "some_conversion_from_boolean_to_int(" +
super.render( firstArgumentType, arguments, factory ) +
")";
}
}
);
}
}
您可以尝试使用LIKE操作标准:
where company.num like '%514619915'
然后过滤掉使用Java正则表达式的不想要的。 这应该减少将返回不需要的行数。
因为它以“%”开始,这将不会使用索引。
您不能访问特定的数据库功能,除非JPAQL / HQL提供一种方式来做到这一点,也不提供对正则表达式什么。 所以你需要写一个本地的SQL查询中使用正则表达式。
在另一个,而且很重要的一点,几个同事(的Oracle DBA)告诉我在甲骨文从来没有使用正则表达式,因为它们不能被索引,这在DB执行完整扫描DB结束了。 如果表中有几个条目,那么它的确定,但是如果它有大量的行,它可能会削弱性能。
对于那些使用Hibernate则以sqlRestriction(休眠版本4.2.7)
Criterion someCriterion = Restrictions.sqlRestriction("regexp_like (column_name, ?, 'i')", "(^|\\s)"+searchValue+"($|\\s|.$)", StringType.INSTANCE);
或者另一种选择是在Oracle中创建类似的功能,这将返回基于运算结果的数值。 类似的东西
CREATE OR REPLACE FUNCTION MY_REGEXP_LIKE(text VARCHAR2, pattern VARCHAR2)
RETURN NUMBER
IS function_result NUMBER;
BEGIN
function_result := CASE WHEN REGEXP_LIKE(text, pattern)
THEN 1
ELSE 0
END;
RETURN(function_result);
END MY_REGEXP_LIKE;
你将能够使用
MY_REGEXP_LIKE('bananas', 'a') = 1