如何在 HQL 中使用一个 like 运算符在多列中进行搜索(休眠 sql)

How to search in multiple columns using one like operator in HQL (hibernate sql)

希望有人能帮我解决这个 HQL 查询。

我正在使用:

Query query = session.createQuery(sql);

其中 sql 是:

select distinct c.id from EstateConsumer as c where c.clientId = ? and  (c.vehicleReg1 or c.vehicleReg2) like ?

但出现以下异常:

org.hibernate.hql.ast.QuerySyntaxException: unexpected AST node: or near line 1, column 121

那么如何通过一个 "like" 来使用 "OR" 语法呢?

但以下内容有效:

select distinct c.id from EstateConsumer as c where c.clientId = ? and  c.vehicleReg1 like ? or c.vehicleReg2 like ?

但我不想使用多个 "like" 的

您可以使用 REGEX 解决您的问题,例如:

REGEXP_LIKE('Hello world', 'Hello', 'mars') = 1

因此您可以替换您的查询:

select ... where c.clientId = ? and  c.vehicleReg1 like ? or c.vehicleReg2 like ?

通过在此处使用此查询:

SELECT ... WHERE c.clientId = ? and REGEXP_LIKE(?, c.vehicleReg1, c.vehicleReg2) = 1
-- -------------------------------------^^

这意味着如果您的值 ? 类似于 c.vehicleReg1c.vehicleReg2 return 1 否则匹配是错误的


备注

@mm759, because of the way the program is coded and structured... it passes only 2 parameters (one for clientId and one for the multiple vehicleReg columns)

您可以在查询的多个位置使用相同的参数,如下所示:

q = getEntityManager().createNamedQuery(
"select ... where c.clientId = :par1 and  c.vehicleReg1 like :par2 or c.vehicleReg2 like :par2");
//-------------------------------^^----------------------------^^--------------------------^^

q.setParamettre("par1", "value1");
q.setParamettre("par2", "value2");

@YCF_L 提出的 regexp_like 变体等复杂变体可能包含额外的性能开销,如果仅仅是因为 DBMS 无法将此类查询优化到与使用 'familiar' 运算符。

我会寻求重用参数的解决方案。

你说,

because of the way the program is coded and structured... it passes only 2 parameters (one for clientId and one for the multiple vehicleReg columns)

我不明白为什么不能只捕获其中一个参数并重新使用它。 YCL_F 在他的更新中给出了一个非常好的示例,但是只要您使用的是 JPA,为什么不寻求完整的 JPA 解决方案呢?这增加了好处,因为它是类型安全的、重构安全的,并且可以(更好地)缓存比本地 SQL 查询。

例如,

CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaQuery<C> jpaquery = cb.createQuery(C.class);
Root<C> root = jpaquery.from(C.class);

jpaquery.where(cb.and(cb.equal(root.get(C_.clientId), parameter1),cb.or(cb.like(root.get(C_.vehicleReg1), parameter2), cb.like(root.get(C_.vehicleReg2), parameter2)));
jpaQuery.select(...);

return getEntityManager().createQuery(jpaQuery).getResultList();