9 Stimmen

Offenlegung von Hibernate-Kriterien über die Dienst-API

Dies ist eher eine Frage des Designs als der Implementierung, und es wird lang werden, also haben Sie Geduld mit mir. Es ist am besten mit einem Beispiel zu erklären:

Nehmen wir an, ich habe eine Wirtschaftseinheit namens Produkt mit einer Reihe von Eigenschaften ( Name , Preis , Anbieter usw...).

Es wird durch eine Schnittstelle dargestellt ( Produkt ) und Umsetzung ( ProductImpl , abgebildet in Hibernate) sowie eine grundlegende CRUD-Dienstschnittstelle ( ProduktDienstleistung ) und Umsetzung ( ProductServiceImpl ).
Produkt y ProduktDienstleistung sind als API offengelegt, ihre Implementierungen jedoch nicht.

Ich möchte eine List findProducts(QueryCriteria Kriterien) Methode zu ProduktDienstleistung die eine Liste von Produkten zurückgeben würde, die bestimmte Kriterien erfüllen. Die Anforderungen sind:

  1. Abfrage durch direkte Produkt Eigenschaften (z.B. product.price gt 50.0 )
  2. Abfrage durch Assoziation (z.B. product.vendor.name = "Oracle" )
  3. Ergebnisse sortieren (z.B. order by product.vendor.name desc, product.price asc" )
  4. Zusätzliche Filter anwenden. Im Gegensatz zu den obigen 3 Punkten, die alle vom API-Kunden angegeben werden, kann der Dienst zusätzliche Filter auf der Grundlage der Identität des Kunden anwenden (z. B. kann der Kunde, der diese Methode aufruft, darauf beschränkt sein, nur Produkte eines bestimmten Herstellers zu sehen). Solche Filter haben Vorrang vor allen vom Kunden angegebenen Kriterien (z. B. wenn der Filter auf product.vendor.name = "Microsoft" sollte die Abfrage in (2) eine leere Ergebnismenge ergeben.

Die Frage ist also, was sollte QueryCriteria Schnittstelle, die von einer solchen Methode verwendet wird, aussehen? Mir fallen 3 Lösungen ein, und keine von ihnen gefällt mir:

  • Erlauben Sie den Kunden, HQL (beginnend mit der "where"-Klausel) direkt anzugeben. Dies ist die einfachste Lösung, aber auch die problematischste in Bezug auf die Sicherheit. Selbst wenn man davon ausgeht, dass Filter (#4 oben) einfach genug sind, um über die Session-Filter von Hibernate implementiert zu werden, muss HQL immer noch geparst werden, um - zumindest - sicherzustellen, dass Abfrageparameter als Parameter angegeben und nicht inlined werden.
  • Verwenden Sie die dünn verpackte Hibernate FreistehendKriterien anstelle von QueryCriteria . "Thinly wrapped", weil es dem Client nicht erlaubt werden kann, eine FreistehendKriterien direkt, denn es gäbe keine Möglichkeit zu kontrollieren, für welche zugeordnete Entität sie erstellt wurde. Außerdem wäre dies nicht so flexibel wie HQL, da einige Abfragen nicht einfach (oder gar nicht) über die Criteria-API ausgedrückt werden können. Wie beim HQL-Ansatz sind die Filter (Nr. 4 oben) auf Hibernate-Sitzungsfilter beschränkt.
  • Mein eigenes schreiben QueryCriteria Schnittstelle/Implementierung, die hinter den Kulissen entweder DetachedCriteria oder HQL bilden wird. Dies ist zwar wahrscheinlich die flexibelste Lösung, aber es muss eine Menge Code aus der Criteria-API dupliziert werden, was nicht gerade ideal ist.

Für Kommentare zur Gültigkeit der oben genannten Ansätze oder - ich drücke die Daumen - für einfache, elegante Lösungen, die mir nicht eingefallen sind, wäre ich sehr dankbar.

P.S. In meinem speziellen Fall sind alle API-Clients intern und "halb-vertrauenswürdig" - das heißt, ich mache mir weniger Sorgen darüber, dass jemand absichtlich etwas kaputt macht, als über schlechte Programmierung, die zu einem kartesischen Produkt aus 5 Tabellen führt :-) Es wäre jedoch schön, eine Lösung zu finden, die der öffentlichen Nutzung der API standhält.

0voto

IAdapter Punkte 58848

Je pense Abfrage nach Beispiel würde hier sehr gut funktionieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X