Wenn ich als jemand spreche, der viel Zeit mit JPA (Java Persistence API, im Grunde die standardisierte ORM-API für Java / J2EE / EJB) verbracht hat, zu der Hibernate, EclipseLink, Toplink, OpenJPA und andere gehören, teile ich einige meiner Beobachtungen.
- ORMs sind nicht schnell. Sie können angemessen sein und sind meistens in Ordnung, aber in einer Umgebung mit hohem Volumen und geringer Latenz sind sie ein Nein-Nein.
- In allgemeinen Programmiersprachen wie Java und C # benötigen Sie eine Menge Magie, damit sie funktionieren (z. B. Weben in Java, Instrumentierung usw.).
- Wenn Sie ein ORM verwenden, anstatt sich weiter von SQL zu entfernen (was die Absicht zu sein scheint), werden Sie erstaunt sein, wie viel Zeit Sie damit verbringen, XML und / oder Anmerkungen / Attribute zu optimieren, damit Ihr ORM performantes SQL generiert.
- Für komplexe Abfragen gibt es wirklich keinen Ersatz. Wie in JPA gibt es einige Abfragen, die in Raw SQL einfach nicht möglich sind, und wenn Sie Raw SQL in JPA verwenden müssen, ist es nicht schön (C # /. Net hat zumindest dynamische Typen - var - was sehr viel ist schöner als ein Objektarray);
- Bei der Verwendung von ORMs gibt es sehr viele "Fallstricke". Dies schließt unbeabsichtigtes oder unerwartetes Verhalten ein, die Tatsache, dass Sie die Fähigkeit zum Ausführen von SQL-Updates für Ihre Datenbank (mithilfe von refresh () in JPA oder ähnlichen Methoden einbauen müssen, da JPA standardmäßig alles zwischenspeichert, damit keine direkte Datenbank abgefangen wird Update - Das Ausführen direkter SQL-Updates ist eine häufige Aktivität zur Produktionsunterstützung.
- Die objektrelationale Nichtübereinstimmung wird immer Probleme verursachen. Bei einem solchen Problem besteht ein Kompromiss zwischen Komplexität und Vollständigkeit der Abstraktion. Manchmal hatte ich das Gefühl, dass JPA zu weit gegangen ist und ein echtes Gesetz zur Verringerung der Rendite getroffen hat, bei dem die Komplexität nicht durch die Abstraktion gerechtfertigt war.
Es gibt noch ein anderes Problem, das etwas näher erläutert werden muss.
Das traditionelle Modell für eine Webanwendung besteht darin, eine Persistenzschicht und eine Präsentationsschicht zu haben (möglicherweise mit einem Dienst oder anderen Schichten dazwischen, aber dies sind die beiden wichtigsten für diese Diskussion). ORMs erzwingen eine starre Ansicht von Ihrer Persistenzschicht bis zur Präsentationsschicht (dh Ihren Entitäten).
Einer der Kritikpunkte an mehr rohen SQL-Methoden ist, dass Sie am Ende all diese VOs (Wertobjekte) oder DTOs (Datenübertragungsobjekte) haben, die von nur einer Abfrage verwendet werden. Dies wird als Vorteil von ORMs angepriesen, weil Sie das loswerden.
Diese Probleme verschwinden nicht mit ORMs, sondern gehen einfach auf die Präsentationsebene über. Anstatt VOs / DTOs für Abfragen zu erstellen, erstellen Sie benutzerdefinierte Präsentationsobjekte, normalerweise eines für jede Ansicht. Wie ist das besser IMHO ist es nicht.
Ich habe darüber in ORM oder SQL geschrieben: Sind wir schon da? .
Meine derzeitige Persistenztechnologie (in Java) ist ibatis. Es ist ein ziemlich dünner Wrapper um SQL, der mehr als 90% dessen leistet, was JPA kann (es kann sogar verzögertes Laden von Beziehungen durchführen, obwohl es nicht gut dokumentiert ist), aber mit weitaus weniger Aufwand (in Bezug auf Komplexität und tatsächlichen Code).
Dies kam letztes Jahr in einer GWT-Anwendung zum Ausdruck, die ich schrieb. Viele Übersetzungen von EclipseLink zu Präsentationsobjekten in der Service-Implementierung. Wenn wir ibatis verwendet hätten, wäre es viel einfacher gewesen, die entsprechenden Objekte mit ibatis zu erstellen und sie dann ganz nach oben und unten im Stapel zu übergeben. Einige Puristen könnten argumentieren, dass dies Bad ™ ist. Vielleicht (theoretisch), aber ich sage Ihnen was: Es hätte zu einfacherem Code, einem einfacheren Stack und mehr Produktivität geführt.