2009-08-27 19 views
75

Próbuję napisać kwerendę JPQL z podobnego klauzulą:Parametr w jak klauzula JPQL

LIKE '%:code%' 

Chciałbym mieć kod = 4 i znaleźć

 
455 
554 
646 
... 

nie mogę przejść :code = '%value%'

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

ponieważ w innym miejscu potrzebuję :value nie opakowany przez % znaków. Jakaś pomoc?

+2

@ Manuele Piastra: Czy odpowiedź poniżej nie jest tym, czego szukałeś? – wmorrison365

Odpowiedz

157

Jeśli nie

LIKE :code 

a następnie zrobić

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

Następnie wartość pozostaje wolny od '%' znak. Jeśli chcesz użyć go gdzieś indziej w tym samym zapytaniu, użyj po prostu innej nazwy parametru niż "kod".

+9

Dla celów rekordu nie pozostawia to otwartego na ataki przy wtrysku JPQL, ponieważ wartość ta jest automatycznie poprawnie odbierana. –

+1

To "%" + this.value + "%" 'jest tym, co zostało zmienione. – Gustavo

+0

Jak zrobić, aby ta wielkość liter nie miała znaczenia? –

50

Nie używam nazwanych parametrów dla wszystkich zapytań. Na przykład nietypowe jest używanie nazwanych parametrów w JpaRepository.

Aby obejść używam JPQL CONCAT funkcję (kod naśladować początek z):

@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); 
} 

znalazłem tę technikę w doskonałych docs: http://openjpa.apache.org/builds/1.0.1/apache-openjpa-1.0.1/docs/manual/jpa_overview_query.html

4

Można użyć JPA LOCATE function.

umiejscowienie (searchString, candidateString [, startIndex]): Zwraca pierwszy indeks z searchString w candidateString. Pozycje są oparte na 1. Jeśli ciąg nie zostanie znaleziony, zwraca 0.

FYI: Dokumentacja na my top google hit miał parametry odwrócone.

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

dla mnie najlepsze rozwiązanie - bez konkatenacji, bez iniekcji SQL. – hgoebl

2

Wystarczy pominąć „”

LIKE %:code% 
0

Nie wiem, czy jestem późno lub poza zakresem, ale moim zdaniem mógłby zrobić to lubią:

String orgName = "anyParamValue"; 

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

q.setParameter("orgName", orgName);