我有一个多标准表单,并使用 CriteriaBuilder 来构建 sql。对于本地联系人条件,我需要使用 regexp_like 函数来搜索逗号分隔数字字符串中的数字字符串,即在字符串中搜索“234”,例如“1234,2345,6789,234”,它应该只返回完全匹配的记录,而不返回部分匹配的记录。
我已经在 Oracle 中测试了我的 regexp_like 语法,我使用的模式有效并给出了我期望的结果。
下面使用简单的java代码like有效(简化版本,仅考虑两个标准)
public List<ExpSessionInfoLightVO> findBySchedulingSearchExperimentsParams(String categoryCode, Integer categoryCounter,
String expSessionPlaceHolderCategory, Date startsAfterDate, Date startsBeforeDate, Date endsAfterDate, Date endsBeforeDate,
Long beamlinePk, Long pseudoBeamlinePk, Long runPk, Long scientistPk, String scientistRole, Long localContactPk,
boolean showHiddenProposals, boolean withIHR) throws Exception {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery();
Root<ExpSessionInfoLightVO> esilvo = cq.from(ExpSessionInfoLightVO.class);
// Constructing list of parameters
List<Predicate> predicates = new ArrayList<>()
// Local contact criteria
if (localContactPk != null && localContactPk > 0) {
Expression<String> path = esilvo.get("lcPks");
Predicate localContact = cb.like(path, "%" + MISNumberUtils.toString(localContactPk) + "%");
predicates.add(localContact);
}
// Run criteria
if (runPk != null && runPk > 0) {
Predicate beamline = cb.equal(esilvo.get("runNo"), runPk);
predicates.add(beamline);
}
cq.select(esilvo).where(predicates.toArray(new Predicate[] {}));
cq.orderBy(cb.asc(esilvo.get("startDate")));
System.out.println(em.createQuery(cq).unwrap(org.hibernate.Query.class).getQueryString());
// execute query
return em.createQuery(cq).getResultList();
}
它生成以下查询:
select generatedAlias0 from ExpSessionInfoLightVO as generatedAlias0 where ( generatedAlias0.lcPks like :param0 ) and ( generatedAlias0.runNo=114L ) order by generatedAlias0.startDate asc
但是,如果我将本地联系人条件代码更改为:
if (localContactPk != null && localContactPk > 0) {
Expression<String> regExpr = cb.literal("(^|\\s|\\w)(" + MISNumberUtils.toString(localContactPk) + ")($|\\s|\\w)");
Expression<String> path = esilvo.get("lcPks");
Expression<Boolean> regExprLike = cb.function("regexp_like", Boolean.class, path, regExpr);
Predicate localContact = cb.equal(regExprLike, 1);
predicates.add(localContact);
}
我收到错误java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended
.
尽管遵循给出的指示here https://stackoverflow.com/questions/11793159/how-to-use-oracles-regexp-like-in-hibernate-hql。我已经按照说明注册了该功能:
public class Oracle10gCustomDialect extends Oracle10gDialect {
public Oracle10gCustomDialect() {
super();
registerFunction("instr", new StandardSQLFunction("instr", IntegerType.INSTANCE));
registerFunction("regexp_like",
new SQLFunctionTemplate(StandardBasicTypes.BOOLEAN, "(case when (regexp_like(?1, ?2)) then 1 else 0 end)"));
}
}
并且方言出现在 persistence.xml 文件中
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
我是 java 和 JPA/Hibernate 方面的新手,因此非常感谢您能给我的任何指示。
谢谢