Параметр в предложении Like JPQL


92

Я пытаюсь написать запрос JPQL с подобным предложением:

LIKE '%:code%'

Я хотел бы иметь код = 4 и найти

455
554
646
...

Я не могу пройти :code = '%value%'

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

потому что в другом месте мне :valueне нужно оборачивать %символы. Любая помощь?


2
@Manuele Piastra: Ответ ниже не то, что вы искали?
wmorrison365

Ответы:


170

Если вы сделаете

LIKE :code

а затем сделать

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

Тогда значение останется свободным от знака «%». Если вам нужно использовать его где-то еще в том же запросе, просто используйте другое имя параметра, отличное от 'code'.


9
Для записи, это не оставляет вас уязвимым для атак JPQL-инъекций, потому что this.value автоматически правильно экранируется для вас.
Ласло ван ден Хук

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, кандидатаString [, startIndex]) : возвращает первый индекс searchString в строке кандидата. Позиции отсчитываются от 1. Если строка не найдена, возвращает 0.

К вашему сведению: в документации к моему главному хиту Google были изменены параметры.

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

1
для меня лучшее решение - без конкатенации, без SQL-инъекций.
hgoebl 04

4

Я не знаю, опаздываю ли я или выхожу за рамки, но, на мой взгляд, я мог бы сделать это так:

String orgName = "anyParamValue";

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

q.setParameter("orgName", orgName);

3

В API критериев JPA есть приятный метод 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

Использовать JpaRepositoryили CrudRepositoryкак интерфейс репозитория:

@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());
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.