java - 如何在 LIKE jpql 查询中使用引号?

标签 java spring hibernate jpql

所以,我正在尝试编写一些自定义 JPQL 查询生成器。 我有一个端点,例如:

/api/library/authors/search?query=test tested

在服务层上,此查询参数将被转换为类似以下JPQL查询的smth:

SELECT t FROM Author t WHERE t.fullName LIKE '%test tested%' 
     OR t.firstName  LIKE '%test%' 
     OR t.firstName  LIKE '%tested%' 
     OR t.secondName LIKE '%test%' 
     OR t.secondName LIKE '%tested%'

它对我来说效果很好,但是,firstNamesecondName 表列可能会包含带引号 ' 的值,例如 奥哈拉。那么就不行了。

/api/library/authors/search?query=Tes O'Ha

因此,我尝试将查询中的 ' 替换为双引号 ",如下所示:

SELECT t FROM Author t WHERE t.fullName LIKE "%Tes O'Ha%" 
     OR t.firstName  LIKE "%Tes%" 
     OR t.firstName  LIKE "%O'Ha%" 
     OR t.secondName LIKE "%Tes%" 
     OR t.secondName LIKE "%O'Ha%"

我遇到了一个异常(exception):

org.hibernate.QueryException: unexpected char: '"'

我还尝试替换 \' 上的 '\" 上的 "。所有这些都不起作用并引发异常......

我正在使用 EntityManager 执行此查询:

@Repository
public class SearchFor {
    @PersistenceContext
    private EntityManager entityManager;

    public List execute(String query) {
        return entityManager.createQuery(query).getResultList();
    }      
}

如何搜索包含单引号 ' 的值?

最佳答案

我建议您使用索引或命名参数来创建查询。这将解决您的问题,因为它会自动转义任何命令字符。

类似这样的事情:

em.createQuery("SELECT t FROM TestEntity t WHERE t.fullName LIKE :fullName " 
                + "OR t.firstName  LIKE :firstName " 
                + "OR t.firstName  LIKE :lastName " 
                + "OR t.lastName LIKE :firstName " 
                + "OR t.lastName LIKE :lastName") 
                .setParameter("firstName", firstName) 
                .setParameter("lastName", lastName) 
                .setParameter("fullName", fullName)
                .getResultList();

我假设您从服务层的方法参数中获取您的名字、姓氏、全名。

此外,您当前的实现使您的应用容易受到 SQL/JPQL 攻击,因为用户可以通过 REST 端点注入(inject)恶意代码。

有关 SQL 注入(inject)的更多信息: https://www.baeldung.com/sql-injection

使用命名和索引参数创建查询: https://www.baeldung.com/jpa-query-parameters

关于java - 如何在 LIKE jpql 查询中使用引号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58276876/

相关文章:

java - 在复合键 hibernate xml 中映射复合键

java - 如何将函数式概念应用到 Java 8 中的传统过程算法中?

java - 如何在 Java 中创建另一个列表,给定一个列表,但列出不同的类

Spring Security登录页面与loginProcessingURL

java - 我应该如何使用异步通信实现 GET 端点?

hibernate - Grails Hibernate:在父类(super class)中禁用乐观锁定

mysql - 如何配置Tapestry5、Hibernate、Tomcat7、JNDI、Mysql

java - 根据条件(Java/Guava)从列表中提取第一个匹配项?

java - 确保代理持有消息,直到至少一个消费者得到它

html - 将 css 类添加到输入标签 thymeleaf + spring