如何在LIKE jpql查询中使用报价?

时间:2019-10-07 20:42:32

标签: java spring hibernate jpql

因此,我正在尝试编写一些自定义JPQL查询生成器。 我有一个类似的端点:

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

在服务层上,此query参数将像下面的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表列可能包含带有引号'的值,例如O'Hara。那就行不通了。

/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%"

我有一个例外:

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

我还尝试替换了'上的\'"上的\"。所有这些都不起作用,并抛出一个异常...

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

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

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

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

2 个答案:

答案 0 :(得分:1)

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

类似这样的东西:

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();

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

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

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

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

答案 1 :(得分:1)

我找到了解决方案! 而且...这很简单。仅需将引号(''

)加倍

JPQL查询如下所示:

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%'

就是这样!