Welches Java ORM bevorzugen Sie und warum? [geschlossen]

262

Es ist eine ziemlich offene Frage. Ich werde ein neues Projekt starten und mir verschiedene ORMs ansehen, die in den Datenbankzugriff integriert werden sollen.

Hast du irgendwelche Favoriten? Gibt es welche, von denen Sie raten würden, sich fernzuhalten?

Tom Neyland
quelle
Werfen Sie einen Blick auf Micro-Orms - Thin Wrapper um die DB-Zugriffstechnologie der Plattform - wie sql2o für Java github.com/aaberg/sql2o oder ServiceStack.OrmLite für .NET github.com/ServiceStack/ServiceStack.OrmLite
tomaszkubacki
3
Nachdem ich ORM mehr als 5 Jahre lang verwendet habe, ist meine persönliche Wahl Spring JDBC gegenüber ORM, und zweitbeste ist iBatis (MyBatis). Ich mag den Ruhezustand wegen Lernkurve, weniger Kontrolle und Leistungsproblemen nicht.
Hier ist (auch geschlossen) Liste von leichten JDBC-Wrappern, die als Alternative zu ausgewachsenen Orms verwendet werden können: stackoverflow.com/questions/7137929/…
Vadzim

Antworten:

237

Ich habe die Verwendung von ORMs eingestellt.

Der Grund ist kein großer Fehler im Konzept. Der Ruhezustand funktioniert gut. Stattdessen habe ich festgestellt, dass Abfragen einen geringen Overhead haben und ich viele komplexe Logik in große SQL-Abfragen einpassen und einen Großteil meiner Verarbeitung in die Datenbank verlagern kann.

Verwenden Sie also nur das JDBC-Paket.

David Crawshaw
quelle
81
Bei ORM ist es immer wieder dieselbe Geschichte: eine schöne, schnelle Erstentwicklung und eine große Belastung Ihrer Ressourcen im weiteren Verlauf des Projekts, wenn Sie ORM-bezogene Fehler und Ineffizienzen nachverfolgen. Ich hasse auch die Tatsache, dass es Entwicklern die Idee zu geben scheint, dass sie niemals bestimmte optimierte Abfragen schreiben müssen.
Eelco
7
Hey, gilt das alles für große Projekte im wirklichen Leben?
Santiagobasulto
30
Genau. Ich benutze ORM seit über 3 Jahren und kann nicht sagen, wie viel Zeit verschwendet wurde (noch ist), um Probleme im Zusammenhang mit der Persistenz zu lösen. Wir haben keinerlei Kontrolle darüber, was "unter der Haube" passiert, Konfigurationen sind zu viele, um effizient verwaltet zu werden, und es gibt Verhaltensweisen, die einen verrückt machen könnten. Andererseits unterstütze ich wichtige Datenbanken und muss mich nie um deren Unterschiede kümmern.
marcolopes
58
Warum nicht beide verwenden, abhängig von der Komplexität der Abfrage / Transaktion? Es ist nicht so, dass sie sich gegenseitig ausschließen.
Amphibient
6
@ WillSheppard ja Will. Ich benutze Django ORM ziemlich oft und es funktioniert großartig. Ich denke, der Unterschied könnte in der Dynamik von Python (und Perl) liegen. Die Verwendung eines ORM in Java ist ein Schmerz. Aber in dynamischen Sprachen kann es sehr ausdrucksstark sein. Es gibt einige großartige Projekte zum Einbetten von ORM-Operationen wie DSLs in Python, die großartig sind.
Santiagobasulto
98

Keine, weil ein ORM zu viel Kontrolle mit kleinen Vorteilen nimmt. Die gewonnenen Zeiteinsparungen werden leicht zunichte gemacht, wenn Sie Anomalien beheben müssen, die sich aus der Verwendung des ORM ergeben. Darüber hinaus halten ORMs Entwickler davon ab, SQL und die Funktionsweise relationaler Datenbanken zu lernen und diese zu ihrem Vorteil zu nutzen.

Simon
quelle
4
Ich stimme dieser Aussage zu. Wie viel von der gesamten Entwicklungszeit wird durch das Schreiben von Persistenzcode verbraucht? Ich denke weniger als 10-15%
adrian.tarau
16
Es hängt davon ab, ob. Sicher, wenn Sie nur eine bestimmte Art von Datenbank verwenden, ist es einfach, ohne ORM davonzukommen. Wenn Sie jedoch andere Arten von Datenbanken unterstützen müssen, kann diese schnell weniger verwaltbar werden.
Jason Baker
3
"Die gewonnenen Zeiteinsparungen werden leicht weggeblasen, wenn Sie Anomalien debuggen müssen, die sich aus der Verwendung des ORM ergeben." Dies gilt nicht, wenn die Kompetenzkurve ein anständiger Faktor bei der Auswahl von Technologien ist.
Elsadek
7
Ihr Argument könnte gegen die Verwendung einer Bibliothek vorgebracht werden. Die größten Vorteile von ORMs sind Arbeitseinheiten, Objektzuordnung, Änderungsverfolgung, verzögertes Laden, Migrationen und Beziehungen. Es ist eine wunderbare Sache, user.profile.givenName schreiben zu können und sich nicht darum zu kümmern, in welcher Struktur die Daten dafür gespeichert wurden.
Alex
1
Es kann gegen jede Bibliothek verwendet werden, jedoch in unterschiedlichem Maße. Im Allgemeinen bin ich ein großer Befürworter der Verwendung von Bibliotheken - warum das Rad neu erfinden? In diesem Fall bin ich jedoch der Meinung, dass der Ruhezustand für die meisten Anwendungen zu schwer ist und ein leichteres ORM vorzuziehen wäre. Meine Erfahrungen basieren auf mehrjähriger Erfahrung in der Entwicklung mit Hibernate und dem gründlichen Erlernen seiner Vor- und Nachteile.
Simon
92

Viele ORMs sind großartig. Sie müssen wissen, warum Sie zusätzlich zu JDBC eine Abstraktion hinzufügen möchten. Ich kann Ihnen http://www.jooq.org empfehlen (Haftungsausschluss: Ich bin der Schöpfer von jOOQ, daher ist diese Antwort voreingenommen). jOOQ umfasst das folgende Paradigma:

  • SQL ist eine gute Sache. Viele Dinge können in SQL sehr gut ausgedrückt werden. Eine vollständige Abstraktion von SQL ist nicht erforderlich.
  • Das relationale Datenmodell ist eine gute Sache. Es hat sich in den letzten 40 Jahren als das beste Datenmodell erwiesen. Es sind keine XML-Datenbanken oder wirklich objektorientierten Datenmodelle erforderlich. Stattdessen führt Ihr Unternehmen mehrere Instanzen von Oracle, MySQL, MSSQL, DB2 oder einem anderen RDBMS aus.
  • SQL hat eine Struktur und Syntax. Es sollte nicht mit der String-Verkettung "Low-Level" in JDBC oder der String-Verkettung "High-Level" in HQL ausgedrückt werden. Beide sind anfällig für Syntaxfehler.
  • Die variable Bindung ist bei wichtigen Abfragen in der Regel sehr komplex. DAS sollte abstrahiert werden.
  • POJOs eignen sich hervorragend zum Schreiben von Java-Code zur Bearbeitung von Datenbankdaten.
  • POJOs sind ein Problem beim manuellen Schreiben und Verwalten. Die Codegenerierung ist der richtige Weg. Sie haben kompilierungssichere Abfragen, einschließlich Datentypsicherheit.
  • Die Datenbank steht an erster Stelle. Während sich die Anwendung über Ihrer Datenbank im Laufe der Zeit ändern kann, wird die Datenbank selbst wahrscheinlich länger halten.
  • Ja, Sie haben Prozeduren und benutzerdefinierte Typen (UDTs) in Ihrer Legacy-Datenbank gespeichert. Ihr Datenbank-Tool sollte dies unterstützen.

Es gibt viele andere gute ORMs. Besonders Hibernate oder iBATIS haben eine großartige Community. Aber wenn Sie nach einer intuitiven, einfachen suchen, probieren Sie jOOQ aus. Du wirst es lieben! :-)

Schauen Sie sich dieses Beispiel-SQL an:

  // Select authors with books that are sold out
  SELECT * 
    FROM T_AUTHOR a
   WHERE EXISTS (SELECT 1
                   FROM T_BOOK
                  WHERE T_BOOK.STATUS = 'SOLD OUT'
                    AND T_BOOK.AUTHOR_ID = a.ID);

Und wie es in jOOQ ausgedrückt werden kann:

  // Alias the author table
  TAuthor a = T_AUTHOR.as("a");

  // Use the aliased table in the select statement
  create.selectFrom(a)
        .whereExists(create.selectOne()
                           .from(T_BOOK)
                           .where(T_BOOK.STATUS.equal(TBookStatus.SOLD_OUT)
                           .and(T_BOOK.AUTHOR_ID.equal(a.ID))))));
Lukas Eder
quelle
1
ORM-Tools sind so gut, wie Sie es schaffen, sie richtig zu verwenden. Es gibt Projekte, bei denen ORM-Tools wie ein Zauber wirken, während sie in anderen überhaupt nicht gut passen. Letztendlich liegt es in der Verantwortung des Entwicklungsteams, das richtige Werkzeug für die Projektanforderungen auszuwählen. ORM-Tools sind komplex. Leider wird nur ein Teil aller Entwickler Zeit damit verbringen, zu verstehen, wie sie funktionieren. Der Rest wird nur das Werkzeug beschuldigen und sagen, dass es schlecht ist. Die Frage ist: Bietet die am besten bewertete Antwort den besten Rat? > Verwenden Sie also nur das JDBC-Paket. Wollen wir wirklich einfaches JDBC verwenden?
Vlad Mihalcea
Ich versuche nicht "Die Datenbank steht an erster Stelle" zu lassen. Eine Anwendung enthält die Geschäftsregeln für die Funktionen, die ein Client anfordert, und er fordert fast nie zum Erstellen einer Datenbank auf. Dies ist ein technisches Detail, das während der Implementierung festgelegt wurde.
Kwebble
58

Ruhezustand, da dies im Grunde der Defacto-Standard in Java ist und eine der treibenden Kräfte bei der Erstellung des JPA war. Es wird im Frühjahr hervorragend unterstützt, und fast jedes Java-Framework unterstützt es. Schließlich ist GORM ein wirklich cooler Wrapper, der dynamische Finder usw. mit Groovy verwendet.

Es wurde sogar auf .NET (NHibernate) portiert, sodass Sie es auch dort verwenden können.

Abdullah Jibaly
quelle
4
Ich stimme auch für Hib, aber mit einem wichtigen Zusatz: Wir sollten die JPA-API nur verwenden, selbst wenn die JPA-Implementierung tatsächlich von Hib bereitgestellt wird.
Vladimir Dyuzhev
52

Ruhezustand, weil es:

  • ist stabil - es gibt so viele Jahre, dass es keine größeren Probleme gibt
  • diktiert die Standards im ORM-Bereich
  • implementiert den Standard (JPA) zusätzlich zum Diktat.
  • hat Tonnen von Informationen darüber im Internet. Es gibt viele Tutorials, allgemeine Problemlösungen usw.
  • ist mächtig - Sie können ein sehr komplexes Objektmodell in ein relationales Modell übersetzen.
  • Es unterstützt alle wichtigen und mittleren RDBMS
  • ist einfach zu bearbeiten, sobald Sie es gut gelernt haben

Einige Punkte, warum (und wann) ORM verwendet werden soll:

  • Sie arbeiten mit Objekten in Ihrem System (wenn Ihr System gut entworfen wurde). Selbst wenn Sie JDBC verwenden, werden Sie am Ende eine Übersetzungsebene erstellen, damit Sie Ihre Daten auf Ihre Objekte übertragen können. Ich wette jedoch, dass der Ruhezustand besser übersetzt werden kann als jede maßgeschneiderte Lösung.
  • es beraubt dich nicht der Kontrolle. Sie können die Dinge in sehr kleinen Details steuern. Wenn die API keine Remote-Funktion hat, führen Sie eine native Abfrage aus, und Sie haben sie.
  • Jedes mittelgroße oder größere System kann es sich nicht leisten, eine Tonne Abfragen zu haben (sei es an einem Ort oder über mehrere Bereiche verteilt), wenn es wartbar sein soll
  • wenn die Leistung nicht kritisch ist. Der Ruhezustand erhöht den Leistungsaufwand, der in einigen Fällen nicht ignoriert werden kann.
Bozho
quelle
Wenn ich Hibernate und JPA vergleiche, entscheide ich mich für Hibernate, und wenn ich JPA und JDO vergleiche, entscheide ich mich für JDO! Ich mag JDO sehr, aber ich liebe zwei Funktionen von Hibernate (die in JDO nicht verfügbar sind), eine ist @Filters und die andere ist, dass Sie Versionsfelder (für optimistisches Sperren) normalen Feldern zuordnen können, was in JDO nicht möglich ist .
Amir Pashazadeh
27

Ich würde die Verwendung von MyBatis empfehlen . Es ist eine dünne Schicht über JDBC, es ist sehr einfach, Objekte Tabellen zuzuordnen und trotzdem einfaches SQL zu verwenden. Alles unter Ihrer Kontrolle.

adrian.tarau
quelle
10
Ibatis für komplexe Lesevorgänge und Ruhezustand zum Erstellen, Aktualisieren, Löschen und einfachen Lesen ist die perfekte Wahl.
Darpet
19

Ich hatte wirklich gute Erfahrungen mit Avaje Ebean, als ich eine mittelgroße JavaSE-Anwendung schrieb.

Es verwendet Standard-JPA-Annotationen, um Entitäten zu definieren, macht jedoch eine viel einfachere API verfügbar (kein EntityManager oder irgendein Mist von angehängten / getrennten Entitäten). Außerdem können Sie bei Bedarf problemlos SQL-Abfragen oder einfache JDBC-Aufrufe verwenden.

Es hat auch eine sehr schöne flüssige und typsichere API für Abfragen. Sie können Dinge schreiben wie:

List<Person> boys = Ebean.find(Person.class)
                                  .where()
                                       .eq("gender", "M")
                                       .le("age", 18)
                                  .orderBy("firstName")
                                  .findList();
IgKh
quelle
6
Ich muss ein bisschen komisch sein ... wähle aus Person, bei der Geschlecht = 'M' und Alter <18, geordnet nach Vorname, für mich einfach viel besser aussehen :-)
Eelco
4
Dies ist eine der besseren Ormen, die ich in Java gesehen habe. Die Entscheidung, einen Singleton zu verwenden, ist erfrischend und verschafft ihm einen massiven praktischen Vorteil gegenüber den anderen.
opsb
Ich denke du meinst fließend nicht flüssig.
Montdidier
@opsb Ich denke, technisch gesehen ist es ein Monostat, kein Singleton.
Montdidier
Wie fange ich mit Avaje Ebean ORM an? Irgendwelche Videos Tutorials?
Avinash
11

SimpleORM , weil es unkompliziert und ohne Magie ist. Es definiert alle Metadatenstrukturen in Java-Code und ist sehr flexibel.

SimpleORM bietet ähnliche Funktionen wie Hibernate, indem Daten in einer relationalen Datenbank Java-Objekten im Speicher zugeordnet werden. Abfragen können in Bezug auf Java-Objekte angegeben werden, die Objektidentität wird an Datenbankschlüsseln ausgerichtet, Beziehungen zwischen Objekten werden beibehalten und geänderte Objekte werden automatisch mit optimistischen Sperren in die Datenbank übertragen.

Im Gegensatz zu Hibernate verwendet SimpleORM jedoch eine sehr einfache Objektstruktur und -architektur, die das komplexe Parsen, die Verarbeitung von Bytecode usw. überflüssig macht. SimpleORM ist klein und transparent und in zwei Jars mit einer Größe von nur 79 KB und 52 KB verpackt. Nur eine kleine und optionale Abhängigkeit (Slf4j). (Der Ruhezustand beträgt mehr als 2400 KB plus etwa 2000 KB an abhängigen Gläsern.) Dies macht SimpleORM leicht verständlich und reduziert das technische Risiko erheblich.

David Schmitt
quelle
Ich habe es nicht verwendet, aber ActiveObjects beschreibt sich selbst als eine Art Hibernate-Lite auf ihrer Website, sodass es wahrscheinlich Ähnlichkeiten gibt.
Abdullah Jibaly
10

Eclipse Link aus vielen Gründen, aber vor allem habe ich das Gefühl, dass es weniger Aufblähungen aufweist als andere Mainstream-Lösungen (zumindest weniger Aufblähungen in Ihrem Gesicht).

Oh and Eclipse Link wurde als Referenzimplementierung für JPA 2.0 ausgewählt

Tom Neyland
quelle
5

Obwohl ich die Bedenken hinsichtlich des Java-Ersatzes für Freiform-SQL-Abfragen teile, glaube ich wirklich, dass Leute, die ORM kritisieren, dies aufgrund eines allgemein schlechten Anwendungsdesigns tun.

True OOD wird von Klassen und Beziehungen gesteuert, und ORM bietet Ihnen eine konsistente Zuordnung verschiedener Beziehungstypen und Objekte. Wenn Sie ein ORM-Tool verwenden und am Ende Abfrageausdrücke in der vom ORM-Framework unterstützten Abfragesprache codieren (einschließlich, aber nicht beschränkt auf Java-Ausdrucksbäume, Abfragemethoden, OQL usw.), machen Sie definitiv etwas falsch, dh Ihr Klassenmodell Höchstwahrscheinlich werden Ihre Anforderungen nicht so unterstützt, wie sie sollten. Für ein sauberes Anwendungsdesign sind keine Abfragen auf Anwendungsebene erforderlich. Ich habe viele Projekte überarbeitet, bei denen die Leute anfingen, ein ORM-Framework auf dieselbe Weise zu verwenden, wie sie zum Einbetten von SQL-Zeichenfolgenkonstanten in ihren Code verwendet wurden, und am Ende waren alle überrascht, wie einfach und wartbar die gesamte Anwendung wird, sobald Sie übereinstimmen Erweitern Sie Ihr Klassenmodell mit dem Nutzungsmodell. Zugegeben, für Dinge wie Suchfunktionen usw. benötigen Sie eine Abfragesprache, aber selbst dann sind Abfragen so stark eingeschränkt, dass das Erstellen einer noch komplexeren ANSICHT und das Zuordnen zu einer schreibgeschützten persistenten Klasse viel besser zu pflegen und zu betrachten ist als das Erstellen von Ausdrücken in einer Abfragesprache im Code Ihrer Anwendung. Der VIEW-Ansatz nutzt auch Datenbankfunktionen und kann über die Materialisierung in Bezug auf die Leistung viel besser sein als jedes handgeschriebene SQL in Ihrer Java-Quelle. Daher sehe ich keinen Grund für eine nicht triviale Anwendung, ORM NICHT zu verwenden. Aber selbst dann sind Abfragen so stark eingeschränkt, dass es viel besser ist, eine noch komplexere ANSICHT zu erstellen und diese einer schreibgeschützten persistenten Klasse zuzuordnen, als Ausdrücke in einer bestimmten Abfragesprache im Code Ihrer Anwendung zu erstellen. Der VIEW-Ansatz nutzt auch Datenbankfunktionen und kann über die Materialisierung in Bezug auf die Leistung viel besser sein als jedes handgeschriebene SQL in Ihrer Java-Quelle. Daher sehe ich keinen Grund für eine nicht triviale Anwendung, ORM NICHT zu verwenden. Aber selbst dann sind Abfragen so stark eingeschränkt, dass es viel besser ist, eine noch komplexere ANSICHT zu erstellen und diese einer schreibgeschützten persistenten Klasse zuzuordnen, als Ausdrücke in einer bestimmten Abfragesprache im Code Ihrer Anwendung zu erstellen. Der VIEW-Ansatz nutzt auch Datenbankfunktionen und kann über die Materialisierung in Bezug auf die Leistung viel besser sein als jedes handgeschriebene SQL in Ihrer Java-Quelle. Daher sehe ich keinen Grund für eine nicht triviale Anwendung, ORM NICHT zu verwenden.

Mirko Klemm
quelle
11
Wenn Sie Anwendungen auf einem dauerhaften Speicher erstellen, wie es viele von uns tun, unabhängig davon, ob es sich um ein RDBMS oder eine NoSQL-Variante handelt, verfügt dieser Speicher über eine eigene effiziente Methode, um darauf zuzugreifen. Der Versuch, zu viel davon zu abstrahieren, ist einfach Überentwicklung. Wenn man übermäßig eifrig mit 'True OOD' umgeht, bekommt man diese Astronautenarchitekturen, für die Java berüchtigt ist.
Eelco