Parameter in der Like-Klausel JPQL


90

Ich versuche, eine JPQL-Abfrage mit einer Like-Klausel zu schreiben:

LIKE '%:code%'

Ich hätte gerne Code = 4 und finde

455
554
646
...

Ich kann nicht bestehen :code = '%value%'

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

denn an einem anderen Ort brauche ich mich :valuenicht von den %Zeichen einzuwickeln . Irgendeine Hilfe?


2
@ Manuele Piastra: Ist die Antwort unten nicht das, wonach Sie gesucht haben?
wmorrison365

Antworten:


169

Wenn Sie tun

LIKE :code

und dann tun

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

Dann bleibt der Wert frei vom% -Zeichen. Wenn Sie es an einer anderen Stelle in derselben Abfrage verwenden müssen, verwenden Sie einfach einen anderen Parameternamen als 'Code'.


9
Dies lässt Sie nicht für JPQL-Injection-Angriffe offen, da this.value für Sie automatisch ordnungsgemäß maskiert wird.
László van den Hoek

3
Dies "%" + this.value + "%"ist, was entkommen ist.
Gustavo

2
Wie kann ich die Groß- und Kleinschreibung nicht berücksichtigen?
EM-Creations

55

Ich verwende nicht für alle Abfragen benannte Parameter. Beispielsweise ist es ungewöhnlich, benannte Parameter in JpaRepository zu verwenden .

Um dies zu umgehen, verwende ich die JPQL CONCAT- Funktion (dieser Code emuliert den Anfang mit ):

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

Ich habe diese Technik in hervorragenden Dokumenten gefunden: http://openjpa.apache.org/builds/1.0.1/apache-openjpa-1.0.1/docs/manual/jpa_overview_query.html


1
Hinweis: CONCAT (? 2, '%') fügt am Ende des Parameters '%' hinzu. Verwenden Sie CONCAT ('%' ,? 2, '%'), um es am Anfang und Ende des Parameters hinzuzufügen.
Muizz Mahdy

7

Sie können die JPA LOCATE-Funktion verwenden .

LOCATE (searchString, CandidateString [, startIndex]) : Gibt den ersten Index von searchString in CandidateString zurück. Die Positionen basieren auf 1. Wenn die Zeichenfolge nicht gefunden wird, wird 0 zurückgegeben.

Zu Ihrer Information: In der Dokumentation zu meinem Top-Google-Hit wurden die Parameter umgekehrt.

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

1
Für mich die beste Lösung - keine Verkettung, keine SQL-Injection.
Hgoebl

4

Ich weiß nicht, ob ich zu spät komme oder nicht, aber meiner Meinung nach könnte ich es so machen:

String orgName = "anyParamValue";

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

q.setParameter("orgName", orgName);

2

Es gibt eine nette like () -Methode in der JPA-Kriterien-API. Versuchen Sie das zu nutzen, hoffe es wird helfen.

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. Verwenden Sie die folgende JPQL-Abfrage.

Wählen Sie i aus Instructor i aus, wobei i.Adresse LIKE CONCAT ('%',: Adresse, '%') ");

  1. Verwenden Sie den folgenden Kriteriencode für dasselbe:

    @Test public void findAllHavingAddressLike () {CriteriaBuilder cb = KriterienUtils.criteriaBuilder (); CriteriaQuery cq = cb.createQuery (Instructor.class); Root root = cq.from (Instructor.class); printResultList (cq.select (root) .where (cb.like (root.get (Instructor_.address), "% # 1074%"))); }}


0

Lass einfach das '' weg

LIKE %:code%

Downvote: funktioniert nicht, dies ändert den Parameternamen in Code%
kaiser

0

Verwenden Sie jpqlRepository oder rawRepository in der Repository-Schnittstelle

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

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

}}

  @Service(value="customerService")
  public class CustomerServiceImpl implements CustomerService {
 
  @Override
  public List<Customer> pattern(String text) throws Exception {
  
 List<CustomerEntity> searchList = customerRepository.findByN(text.toLowerCase());}

}}

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.