2016-05-03 3 views
0

zu suchen Ich arbeite an einem Spring-MVC-Projekt, in dem ich Hibernate als das ORM-Tool verwende. Eines der Merkmale des Projekts ist, dass es nach anderen Benutzern suchen kann, indem es verschiedene Parameter wie Land, Stadt usw. angibt. Nun würde ich gerne mehrere Länder für die Suche durchgehen. Aus diesem Grund sende ich eine : getrennte Namen von Ländern an die Methode.HQL: Doppelpunkt getrennte Strings für mehrere Parameter hinzufügen, um mit

Da die Methode ursprünglich nur für ein einzelnes Land galt, habe ich die Abfrage so geändert, dass sie in dieser Reihenfolge funktioniert. Ist dies der richtige Weg, um mehrere Parameter zu übergeben, da die Abfrage komplex ist? Vielen Dank.

@Override 
public List<Student> addHostSearchHistory(HostSearchHistory hostSearchHistory, Long hostId) { 

    String queryString = giveMeFormattedHostSearchString("AND",hostSearchHistory); 

    Query query = session.createQuery(queryString); 

    if (!(hostSearchHistory.getCity() == null)) { 
     if (!(hostSearchHistory.getCity().equals(""))) { 
      query.setParameter("city", "%"+hostSearchHistory.getCity().toUpperCase()+"%"); 
     } 
    } 
    List<Student> studentList = query.list(); 

    Query query1 = session.createQuery(giveMeFormattedHostSearchString("OR",hostSearchHistory)); 
    if (!(hostSearchHistory.getCity() == null)) { 
     if (!(hostSearchHistory.getCity().equals(""))) { 
      query1.setParameter("city", "%"+hostSearchHistory.getCity().toUpperCase()+"%"); 
     } 
    } 

} 

private String giveMeFormattedHostSearchString(String clause, HostSearchHistory hostSearchHistory){ 
    StringBuilder sb = new StringBuilder(); 
    sb.append("from Student as s where "); 

    if (!(hostSearchHistory.getCountry() == null)) { 
     if (!(hostSearchHistory.getCountry().isEmpty())) { 
      String[] countries = hostSearchHistory.getCountry().split(":"); 
      sb.append("("); 
      for(String s : countries){ 
       sb.append(" ").append("upper(s.studentCountry) like ").append(s); 
      } 
      sb.append(")"); 


     } 
    } 
    if (!(hostSearchHistory.getCity() == null)) { 
     if (!(hostSearchHistory.getCity().isEmpty())) { 
      sb.append(" ").append(clause).append(" ").append("upper(s.city) like :city"); 
     } 
    } 
} 

Gibt es eine bessere weniger fehleranfällig Art und Weise für mehrere Länder zu suchen .. Bitte beachten Sie, ich habe 3 enthalten Parameter nur Unordnung zu vermeiden. Vielen Dank.

+0

Können Sie Ihren Code zumindest richtig formatieren? Und bitte nur verwandten Code in Ihrer Frage (Keine Ahnung, wie die StudentList und Führerschein auf Ihre Frage bezogen ist) –

+0

@AdrianShum: Danke. Ich habe den kommentierten Code und den Führerschein entfernt. Ich habe nur die Stadt als Referenz behalten, um zu sehen, wie die Abfrage strukturiert ist. Vielen Dank. :-) –

+0

nur wundern, ist es wirklich schwer, den Code richtig eingerückt? ... –

Antwort

1

(basierend auf Kommentar in Frage Extrahiert)

Wenn es ist einfach ein foo.country in (:countryList) dann Hibernate oder Spring Data helfen können. Für Ihren Fall, dass Sie die Liste der Länder durchsuchen müssen, die LIKE verwenden, müssen Sie es manuell erstellen. Ihre Art der Konstruktion (direkte Einbettung des Werts in die resultierende Abfrage) ist nicht vorzuziehen, da sie fehleranfällig ist und Ihren Code für SQL-Injection öffnet.

Eine der Methoden zum Ausführen einer ordnungsgemäßen Abfragekonstruktion ist die Verwendung der Kriterien-API.

1

Sie extrahieren besser die Abfragegenerierungslogik aus dem Dao. Sie können es an eine andere Klasse delegieren oder einfach eine Methode in diesem Dao erstellen. Wenn die Dinge jedoch groß werden, ist es besser, sie an eine andere Klasse zu delegieren.

Übrigens, Federdaten jpa hat die Logik für die Abfragegenerierung für uns erledigt. Es kann fast alle Bedürfnisse in CRUD erfüllen. Sie können es sich ansehen.

+0

obwohl ich Spring Data seit geraumer Zeit und ich liebte es, was OP versucht zu tun scheint nicht etwas von Spring Data unterstützt (Sammlung von Werten mit LIKE-Klausel) –

+0

Ja, Sie haben Recht . Es kann nicht wirklich. –

Verwandte Themen