如何在 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.vehicleReg1
或 c.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();
希望有人能帮我解决这个 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.vehicleReg1
或 c.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();