当前位置: 首页 > 知识库问答 >
问题:

LIKE语句导致Ignite2.7上使用QueryDSL进行不支持的查询

俞飞鸣
2023-03-14

在Spring Boot应用程序中,我们使用queryDSL访问数据库。应用程序将打印表中匹配(用户输入依赖)搜索参数的所有项。

    null
package example;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "location")
public class LocationEntity {

    @Id
    @GeneratedValue
    @Column(name = "id", nullable = false)
    private Long id;

    @Column(name = "name", nullable = false)
    private String name;

    public LocationEntity() {
        // -
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
package example;

import com.querydsl.core.types.dsl.EntityPathBase;
import com.querydsl.core.types.dsl.NumberPath;
import com.querydsl.core.types.dsl.StringPath;

public class QLocationEntity extends EntityPathBase<LocationEntity> {
    private static final long serialVersionUID = 1L;

    public static final QLocationEntity DEFAULT = new QLocationEntity("loc_1");

    public final NumberPath<Long> id = createNumber("id", Long.class);

    public final StringPath name = createString("name");

    public QLocationEntity(String tableAlias) {
        super(LocationEntity.class, tableAlias);
    }
}

类似于

package example;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.stereotype.Repository;

@Repository
public interface LocationRepository extends JpaRepository<LocationEntity, Long>,
        /* needed for query DSL. */
        QuerydslPredicateExecutor<LocationEntity> {
    /*
     * We don't need custom methods.
     */
}

和一个类似于

package example;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;

@Service
public class LocationRepositoryHelper {
    protected final Log LOG = LogFactory.getLog(getClass());

    @Autowired
    private LocationRepository repository;

    public Sort sort = new Sort(Sort.Direction.ASC, "name");

    public Iterable<LocationEntity> findEntities(String paramLocation, boolean autocomplete)
            throws RequestParameterInvalideException {
        Predicate p = generatePredicate(paramLocation, autocomplete);
        if (p != null) {
            return repository.findAll(p, sort);
        } else {
            return repository.findAll(sort);
        }
    }

    BooleanExpression generatePredicate(String location, boolean autocomplete) {
        if ("".equals(location.trim())) {
            return null;
        } else if (autocomplete) {
            return QLocationEntity.DEFAULT.name.startsWith(location);
        } else {
            return QLocationEntity.DEFAULT.name.eq(location);
        }
    }
}

(这个示例远没有我们实际的应用程序代码复杂,但它应该足以证明我们的问题。)

select locationen0_.id as id1_0_, locationen0_.name as name2_0_ from my_location locationen0_ where locationen0_.name like ? escape '!' order by locationen0_.name asc
select locationen0_.id as id1_0_, locationen0_.name as name2_0_ from my_location locationen0_ where locationen0_.name like 'Ber%' escape '!' order by locationen0_.name asc;

我们在Oracle DB(12.*)和Ignite(2.7)上的SQL控制台中手动运行该语句。在Oracle上一切正常,Ignite仍然宣布我们将出现语法错误/不支持的查询。所以我们在Ignite上尝试了一些替代方案...

select locationen0_.id as id1_0_, locationen0_.name as name2_0_ from my_location locationen0_ where locationen0_.name = 'Berlin' order by locationen0_.name asc;
=> all fine, but doesn't return what we want.

select locationen0_.id as id1_0_, locationen0_.name as name2_0_ from my_location locationen0_ where locationen0_.name like 'Berlin' order by locationen0_.name asc;
=> all fine, but still doesn't return what we want.

select locationen0_.id as id1_0_, locationen0_.name as name2_0_ from my_location locationen0_ where locationen0_.name = 'Ber%' order by locationen0_.name asc;
=> still all fine and would return what we want.

select locationen0_.id as id1_0_, locationen0_.name as name2_0_ from my_location locationen0_ where locationen0_.name = 'Berlin' escape '!' order by locationen0_.name asc;
=> all fine (woot??), but wouldn't return what we want.

select locationen0_.id as id1_0_, locationen0_.name as name2_0_ from my_location locationen0_ where locationen0_.name = 'Ber%' escape '!' order by locationen0_.name asc;
=> (the original statement) unsupported query, but is what queryDSL (supposedly) generates and what should return what we want.

我们的第一个结论是:

  1. 点燃知道逃生关键词;使用关键字并不是在所有情况下都会导致问题。
  2. Ignite理解内部带有“%”的like-statements。
  3. Ignite不接受包含“%”和escape关键字的LIKE语句。

共有1个答案

姬朗
2023-03-14

我研究了源代码,结果发现Ignite明确禁止逃跑。我们检查是否提供了ESCAPE,如果提供了则指示错误。

我认为您可以针对Apache Ignite Jira提出问题。

 类似资料:
  • 我试图使用Spring Data进行查询,但我无法使其工作: 堆栈跟踪: 原因:java。lang.IllegalArgumentException:org。冬眠hql。内部的ast。QuerySyntaxException:意外的AST节点:第1行第49列附近的CASE[从Thing t中选择t,其中name LIKE:name和CASE WHEN(:minVal 原因:组织。冬眠hql。内部的

  • 使用 Raw SQL 查询,无需使用 ORM 表定义 多数据库,都可直接使用占位符号 ?,自动转换 查询时的参数,支持使用 Model Struct 和 Slice, Array ids := []int{1, 2, 3} p.Raw("SELECT name FROM user WHERE id IN (?, ?, ?)", ids) 创建一个 RawSeter o := orm.NewOrm

  • 我有以下QueryDSL查询: 它使用计数,因为这是Spring数据用来对结果进行分页的第一个查询。

  • 问题内容: 我正在使用psql在Postgres中查询数据库。我使用以下查询来搜索一个名为 tag 的字段,该字段的数据类型为文本数组: 现在,我需要创建一个查询,以在 标签 字段中搜索以字母“ A”开头的任何单词。我尝试了以下方法: 这给了我一个语法错误。关于如何将LIKE与文本数组结合使用的任何建议? 问题答案: 使用函数将数组转换为行集: 本应算唯一条目表,只需更换你的主键的名称。 话虽这么

  • 问题内容: 我在存储过程中有以下代码。 NOT LIKE语句不起作用,是的,在有人说任何东西之前,COMMENT列中的项目不包含CORE,其他所有列都可以。 有谁知道这是怎么回事? 问题答案: 如果包含,则条件将不匹配。 该查询: 什么也不会返回。 在一列,两者并反对任何搜索字符串将返回。 您能否在一行中发布相关的值,您认为应该将其返回但不是?