如何在 LIKE jpql 查询中使用引号?
How to use quote inside LIKE jpql query?
所以,我正在尝试编写一些自定义 JPQL 查询生成器。
我有一个类似这样的端点:
/api/library/authors/search?query=test tested
在服务层上,此 query
参数将转换为如下 JPQL 查询:
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%'
它对我来说效果很好,但是,firstName
或 secondName
table 列可能包含带有引号 '
的值,例如 O'Hara
.那就不行了
/api/library/authors/search?query=Tes O'Ha
因此,我尝试将 '
替换为双引号 "
以查询 smth,如下所示:
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();
}
}
如何搜索包含单引号 '
的值?
我建议您使用索引或命名参数来创建查询。这将解决您的问题,因为它会自动转义任何命令字符。
像这样:
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 端点注入恶意代码。
更多关于 SQL 注入:
https://www.baeldung.com/sql-injection
使用命名和索引参数创建查询:
https://www.baeldung.com/jpa-query-parameters
我找到了解决办法!
而且……这很简单。只需要将引号加倍,例如 ''
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%'
就是这样!
所以,我正在尝试编写一些自定义 JPQL 查询生成器。 我有一个类似这样的端点:
/api/library/authors/search?query=test tested
在服务层上,此 query
参数将转换为如下 JPQL 查询:
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%'
它对我来说效果很好,但是,firstName
或 secondName
table 列可能包含带有引号 '
的值,例如 O'Hara
.那就不行了
/api/library/authors/search?query=Tes O'Ha
因此,我尝试将 '
替换为双引号 "
以查询 smth,如下所示:
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();
}
}
如何搜索包含单引号 '
的值?
我建议您使用索引或命名参数来创建查询。这将解决您的问题,因为它会自动转义任何命令字符。
像这样:
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 端点注入恶意代码。
更多关于 SQL 注入: https://www.baeldung.com/sql-injection
使用命名和索引参数创建查询: https://www.baeldung.com/jpa-query-parameters
我找到了解决办法!
而且……这很简单。只需要将引号加倍,例如 ''
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%'
就是这样!