相似子句JPQL中的参数


90

我正在尝试使用like子句编写JPQL查询:

LIKE '%:code%'

我想使用code = 4并找到

455
554
646
...

我无法通过 :code = '%value%'

namedQuery.setParameter("%" + this.value + "%");

因为在另一个地方,我不需要:value%字符包装。有什么帮助吗?


2
@Manuele Piastra:以下答案不是您想要的吗?
wmorrison365

Answers:


169

如果你这样做

LIKE :code

然后做

namedQuery.setParameter("code", "%" + this.value + "%");

然后,值将保持无“%”符号。如果您需要在同一查询的其他地方使用它,只需使用'code'以外的其他参数名即可。


9
作为记录,这不会使您容易遭受JPQL注入攻击,因为this.value会自动为您正确转义。
2013年

3
"%" + this.value + "%"是逃脱的。
古斯塔沃

2
我该如何区分大小写?
EM-Creations

55

我不对所有查询都使用命名参数。例如,在JpaRepository中使用命名参数是不寻常的。

要解决此问题,我使用JPQL CONCAT函数(此代码模拟以开头):

@Repository
public interface BranchRepository extends JpaRepository<Branch, String> {
    private static final String QUERY = "select b from Branch b"
       + " left join b.filial f"
       + " where f.id = ?1 and b.id like CONCAT(?2, '%')";
    @Query(QUERY)
    List<Branch> findByFilialAndBranchLike(String filialId, String branchCode);
}

我在出色的文档中找到了这项技术:http : //openjpa.apache.org/builds/1.0.1/apache-openjpa-1.0.1/docs/manual/jpa_overview_query.html


2
注意:CONCAT(?2,'%')会将'%'添加到参数的末尾,使用CONCAT('%',?2,'%')将其添加到参数的末尾。
Muizz Mahdy

7

您可以使用JPA LOCATE函数

LOCATE(searchString,候选人字符串[,startIndex]):返回候选人字符串中searchString的第一个索引。职位基于1。如果找不到该字符串,则返回0。

仅供参考:我最热门的Google命中文档中的参数已颠倒。

SELECT 
  e
FROM 
  entity e
WHERE
  (0 < LOCATE(:searchStr, e.property))

1
对我来说,最好的解决方案-没有串联,没有SQL注入。
hgoebl

4

我不知道我是迟到还是超出范围,但我认为我可以这样做:

String orgName = "anyParamValue";

Query q = em.createQuery("Select O from Organization O where O.orgName LIKE '%:orgName%'");

q.setParameter("orgName", orgName);

2

JPA标准API中有一个不错的like()方法。尝试使用它,希望对您有所帮助。

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery criteriaQuery = cb.createQuery(Employees.class);
Root<Employees> rootOfQuery = criteriaQuery.from(Employees.class);
criteriaQuery.select(rootOfQuery).where(cb.like(rootOfQuery.get("firstName"), "H%"));

1
  1. 使用下面的JPQL查询。
select i from Instructor i where i.address LIKE CONCAT('%',:address ,'%')");
  1. 在以下条件代码中使用相同的代码:
@Test
public void findAllHavingAddressLike() {
    CriteriaBuilder cb = criteriaUtils.criteriaBuilder();
    CriteriaQuery<Instructor> cq = cb.createQuery(Instructor.class);
    Root<Instructor> root = cq.from(Instructor.class);
    printResultList(cq.select(root).where(
        cb.like(root.get(Instructor_.address), "%#1074%")));
}

0

只需删除''

LIKE %:code%

Downvote:不起作用,这会将参数名称更改为code%
kaiser

0

使用JpaRepositoryCrudRepository作为存储库接口:

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {

    @Query("SELECT t from Customer t where LOWER(t.name) LIKE %:name%")
    public List<Customer> findByName(@Param("name") String name);

}


@Service(value="customerService")
public class CustomerServiceImpl implements CustomerService {

    private CustomerRepository customerRepository;
    
    //...

    @Override
    public List<Customer> pattern(String text) throws Exception {
        return customerRepository.findByName(text.toLowerCase());
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.