2016-06-28 11 views
0

Ich habe an einem Java EE-Projekt gearbeitet, das JAX-RS und Hibernate für den Zugriff auf die Datenbank verwendet. Bis jetzt habe ich die Kriterien von Hibernate verwendet, um Querys zu machen, und ich habe eine gute generische Methode, um alle Zeilen einer Tabelle zu bekommen. Das Problem tritt auf, wenn ich nur nach einem Teil einer Tabelle frage. Ich habe mehrere Tabellen, von denen die meisten eine automatisch generierte Int-ID und String-Felder haben. Gewöhnlich haben einige der Zeichenkettenfelder eine eindeutige Beschränkung für sie. Ich muss auf Basis dieser String-Felder Queries schreiben, die zusammen unique sein müssen. Bisher habe ich so benutzten Methoden dafür: (die Service-Klasse ist eine meiner Einheiten)Hibernate generische Abfrage-Methode für Nicht-ID-Spalten?

public Service getService(String serviceGroup, String serviceDefinition){ 
    Service service = new Service(); 

    Session session = getSessionFactory().openSession(); 
    Transaction transaction = null; 

    try { 
     transaction = session.beginTransaction(); 
     Criteria criteria = session.createCriteria(Service.class); 
     criteria.add(Restrictions.eq("serviceGroup", serviceGroup)); 
     criteria.add(Restrictions.eq("serviceDefinition", serviceDefinition)); 
     service = (Service) criteria.uniqueResult(); 
     transaction.commit(); 
    } 
    catch (Exception e) { 
     if (transaction!=null) transaction.rollback(); 
     throw e; 
    } 
    finally { 
     session.close(); 
    } 

    return service; 
} 

Mein Problem ist, dass die Zeilen mit der Restrictions Saiten fest einprogrammiert hat, die die Feldnamen übereinstimmen müssen Meine Entitätsklassen. Das wird problematisch, da ich immer mehr Tabellen habe. (Grundsätzlich habe ich für jede Tabelle die gleiche Methode) Wie könnte ich eine generische Abfrage-Methode erstellen, die wie diese Methode funktioniert? Habe ich eine bessere Option als die Kriterien api? Alles, was mich in die gute Richtung weist, wäre großartig.

Antwort

1

Sie können etwas tun, wie diese

public Service getService(String serviceGroup, String serviceDefinition,Map<String,String> restrictionMap,Class queryClass){ 
Service service = new Service(); 

Session session = getSessionFactory().openSession(); 
Transaction transaction = null; 

try { 
    transaction = session.beginTransaction(); 
    Criteria criteria = session.createCriteria(queryClass); 
     if(null!=restrictionMap && !restrictionMap .isEmpty()){ 
     for(Entry<String,String> entry:restrictionMap.entrySet()){ 
     criteria.add(Restrictions.eq(entry.getKey(), entry.getValue()); 
    } 
    } 
    service = (Service) criteria.uniqueResult(); 
    transaction.commit(); 
} 
catch (Exception e) { 
    if (transaction!=null) transaction.rollback(); 
    throw e; 
} 
finally { 
    session.close(); 
} 

return service; 

}

Restriktionskarte wird die Klasse-Mitgliedsnamen als Schlüssel und den entsprechenden Wert als der Wert in der Karte

+0

Es hat funktioniert, vielen Dank! Ich werde die letzte generische Methode in einem Kommentar für alle Interessierten veröffentlichen. –

0

Finale generische Methode Aussehen haben so für mich:

@SuppressWarnings("unchecked") 
public <T> T get(Class<T> queryClass, Map<String, String> restrictionMap) { 
    T object = null; 

    Session session = getSessionFactory().openSession(); 
    Transaction transaction = null; 

    try { 
     transaction = session.beginTransaction(); 
     Criteria criteria = session.createCriteria(queryClass); 
     if (null != restrictionMap && !restrictionMap.isEmpty()) { 
      for (Entry<String, String> entry : restrictionMap.entrySet()) { 
       criteria.add(Restrictions.eq(entry.getKey(), entry.getValue())); 
      } 
     } 
     object = (T) criteria.uniqueResult(); 
     transaction.commit(); 
    } catch (Exception e) { 
     if (transaction != null) 
      transaction.rollback(); 
     throw e; 
    } finally { 
     session.close(); 
    } 

    return object; 
}