Was halten Sie von einem neuen Java-Persistenz-Tool, das eigentlich kein ORM ist? [geschlossen]

12

Persistenz in Java

In den letzten Jahren habe ich auf dem Gebiet der Persistenzabstraktion in Java Erfahrungen mit Konzepten wie EJB 2.0, Hibernate, JPA und Eigenbau gesammelt. Sie schienen mir eine steile Lernkurve und viel Komplexität zu haben. Als großer Fan von SQL dachte ich außerdem, dass viele Abstraktionsmodelle zu viel Abstraktion über SQL bieten und Konzepte wie "Kriterien", "Prädikate" und "Einschränkungen" erstellen, die sehr gute Konzepte sind, aber nicht SQL.

Die allgemeine Idee der Persistenzabstraktion in Java scheint auf dem objektrelationalen Modell zu beruhen, bei dem RDBMS in gewisser Weise mit der OO-Welt übereinstimmen. Die ORM-Debatte war schon immer eine emotionale, da es anscheinend keine einzige Lösung gibt, die allen zusagt - wenn es überhaupt eine solche Lösung geben kann.

jOOQ

Meine persönliche Präferenz, wie man ORM-bezogene Probleme vermeidet, ist, mich an die relationale Welt zu halten. Nun sollte die Wahl des Datenmodellparadigmas nicht das Thema der Diskussion sein, da es eine persönliche Präferenz ist oder eine Frage, welches Datenmodell für ein konkretes Problem am besten geeignet ist. Die Diskussion, die ich beginnen möchte, dreht sich um mein eigenes Persistenz-Tool namens jOOQ . Ich habe jOOQ entwickelt, um die meisten Vorteile moderner Persistenz-Tools zu bieten:

  • Eine domänenspezifische Sprache basierend auf SQL
  • Quellcodegenerierung, die das zugrunde liegende Datenbankschema auf Java abbildet
  • Unterstützung für viele RDBMS

Hinzufügen einiger Funktionen, die nur wenige moderne Persistenz-Tools bieten (korrigieren Sie mich, wenn ich falsch liege):

  • Unterstützung für komplexes SQL - Unions, verschachtelte Selects, Self-Joins, Aliasing, Case-Klauseln, arithmetische Ausdrücke
  • Unterstützung für nicht standardmäßiges SQL - gespeicherte Prozeduren, UDTs, ENUMS, native Funktionen, Analysefunktionen

Weitere Informationen finden Sie auf der Dokumentationsseite: http://www.jooq.org/learn.php . Sie werden sehen, dass in Linq für C # ein sehr ähnlicher Ansatz implementiert ist, obwohl Linq nicht ausschließlich für SQL entwickelt wurde.

Die Frage

Nun, da ich ein großer Fan von SQL bin, frage ich mich, ob andere Entwickler meine Begeisterung für jOOQ (oder Linq) teilen werden. Ist ein solcher Ansatz zur Persistenzabstraktion realisierbar? Welche Vor- und Nachteile sehen Sie? Wie könnte ich jOOQ verbessern und was fehlt Ihrer Meinung nach? Wo habe ich mich geirrt, konzeptionell oder praktisch?

Kritische, aber konstruktive Antworten sind erwünscht

Ich verstehe, dass die Debatte emotional ist. Es gibt viele großartige Tools, die bereits ähnliche Aufgaben ausführen. Was mich interessiert, ist kritisches, aber konstruktives Feedback, basierend auf Ihren eigenen Erfahrungen oder Artikeln, die Sie vielleicht gelesen haben.

Lukas Eder
quelle
Erledigt es Transaktionen?
Armand
@Alison: Nein, es geht nur um SQL. Die Transaktionsabwicklung ist ein sehr komplexes Geschäft, von dem ich denke, dass viele andere Tools / Frameworks (einschließlich EJB2 / 3) besser abwickeln werden als jOOQ
Lukas Eder
Ich würde dringend einen sehr soliden und detaillierten Anwendungsfall vorschlagen, bei dem Sie zeigen, dass sich Ihr Ansatz hervorragend zur Lösung eignet.
Beachten Sie auch, dass das Bearbeiten von THIS heavy Antworten für zukünftige Leser mehr oder weniger irrelevant und daher unbrauchbar macht. Stellen Sie stattdessen eine neue und bessere Frage.
Hallo Thorbjörn. Sie meinen einen anderen Anwendungsfall als den auf der Beispielseite gezeigten? Oder möchten Sie einige Beispiele in der Frage selbst sehen? Über die Bearbeitung: Du hast im Allgemeinen recht. In diesem Fall hätte ich jedoch gedacht, dass die beiden Antworten, die ich bisher erhalten habe, ungefähr gleich waren ...
Lukas Eder

Antworten:

5

Ich denke, Sie sind auf dem richtigen Weg und sollten mit Ihrer Lösung fortfahren. Einige der vorherigen Kritikpunkte sind zu hart, aber es werden einige berechtigte Punkte angeführt.

Auch ich habe lange und intensiv nach einer ORM-Lösung mit vollem Funktionsumfang gesucht, die meinen Anforderungen entsprach, aber jede Lösung, die ich mir ansah, kam zu kurz. Jeder hat seine Vor- und Nachteile, aber keiner hat wirklich alles getan, was ich wollte. Ich stimme Ihrer Kritik an diesen Lösungen zu - nämlich dass sie im Allgemeinen komplex sind und eine steile Lernkurve aufweisen.

Der Spitzenkandidat müsste der De-facto-Standard sein, Hibernate. Es ist voll funktionsfähig, robust und gut getestet. Ich respektiere es und schätze es für das, was es ist. Jetzt, da ich die Hälfte der Programmierer beleidigen könnte, muss ich auch sagen, dass es ein aufgeblähter und komplexer Teil von nicht performantem Code ist. Ich habe eine ganze Menge Zeit damit verbracht, in seinen Eingeweiden herumzustöbern und zu versuchen, sie zu debuggen und zu verstehen, und ich war nicht beeindruckt von dem, was ich sah. Trotzdem würde ich es als Ausgangspunkt für alle empfehlen, die nach einem guten ORM suchen. Es zeichnet sich durch einfaches CRUD aus, aber ich würde es nicht für performante Massenabfragen wie Data Mining oder Number Crunching verwenden.

Leider ist meine Anwendung mehr von der Sorte der Zahlenverarbeitung (obwohl es auch CRUD gibt), so dass ich mich entschied, meine eigene zu würfeln. Ich wusste von Anfang an, dass es im Vergleich zu den anderen Lösungen unterdurchschnittlich sein würde, aber es würde gut genug sein und mir die Leistung geben, die ich brauchte. Hier ist der wirklich großartige Teil: Es sieht Ihrer Lösung sehr ähnlich!

Ich denke, Sie haben das Beste getan: Sie haben Ihre zugrunde liegenden Überzeugungen als eine Art Leitbild angegeben, und diese Überzeugungen sind richtig. Ich habe offensichtlich auch viel Zeit damit verbracht, über dieses Problem nachzudenken, und es ist schwer zu lösen. Aber im Laufe der Zeit wird die Programmier-Community es besser verstehen und wir werden bessere Lösungen entwickeln. Ein großes Lob an alle bisherigen Bemühungen (insbesondere Hibernate), aber ich denke, wir können es besser machen.

Ihre Lösung verfeinert das Problem besser, löst jedoch nur einen Teil davon. Ich denke, dass ein mehrschichtiger Ansatz uns alles geben kann, was wir wollen. Was Sie sich mit / IMO ausgedacht haben, ist die Grundschicht. Wie Sie vorgeschlagen haben, denke ich, dass diese Ebene am besten automatisch basierend auf einem Datenbankschema generiert wird. Es sollte ein sehr einfaches relationales Objektmodell sein, das direkt auf die Datenbank abgebildet wird und nicht mehr. Sie haben Recht, dass Daten viel länger bestehen als Code. Auf dieser Ebene sollten Daten den Code steuern und nicht umgekehrt. Es würde CRUD sowie performante Bulk-Abfragen unterstützen. Ich würde wahrscheinlich eine Art L1-Cache auf dieser Ebene implementieren.

Andere ORM-Lösungen zeichnen sich jedoch dadurch aus, dass Sie Ihre Objekte auf eine Weise definieren können, die nicht so sehr von der tatsächlichen Struktur der zugrunde liegenden Datenbank abhängt. Für diese Funktionalität würde ich eine weitere Ebene erstellen. Diese Schicht wird notwendigerweise abstrakter, hoffentlich einfacher (auf Kosten der verlorenen Funktionalität) und baut auf der vorherigen Schicht auf. Möglicherweise wird ein L2-Cache verwendet.

Ich bin offen für mehr Ebenen, aber der entscheidende Punkt für mich ist, dass Sie durch die Bereitstellung mehrerer Einstiegspunkte in die Bibliothek jeden Bedarf erfüllen können. Für diejenigen, die eine einfache CRUD-Lösung suchen, die direkt auf Objekte ihrer Wahl abgebildet werden kann, können sie auf der obersten Ebene aufbauen. Für diejenigen, die nach etwas Mächtigerem und Leistungsfähigerem suchen, aber bereit sind, die zusätzliche Komplexität in Kauf zu nehmen, können sie sich in die untere Schicht stecken. Ich würde keine spezielle Abfragesprache erstellen, sondern stattdessen Ihr Abfrageerstellungsobjekt für diesen Zweck verfügbar machen. Und da der Code mehrschichtig ist, ist diese Funktionalität natürlich ohne spezielle Weiterleitung vorhanden.

Ich denke, Sie haben ein Verständnis für den Raum und erfinden das Rad nicht neu, sondern sind in eine etwas andere Nische geraten. Und ehrlich gesagt ist dies ein Rad, das ohnehin verbesserungswürdig ist. Sie stehen vor einem harten Kampf gegen die Kraftpakete der Vergangenheit, aber wenn Ihre Lösung gut ist und ich denke, dass sie in diese Richtung geht, wird sie von sich aus an Popularität gewinnen.

Dale Anderson
quelle
Hallo Dale, danke für deine Ermutigung! Ich mag Ihre Formulierung über die Ebenen und jOOQ, die sich auf der untersten Ebene befinden, mit einer weiteren Abstraktion, die zusätzlich zu jOOQ möglich ist. Das möchte ich angehen, wenn ich mit jOOQ genug Schwung habe. Die Anbindung an JPA und / oder Hibernate steht eindeutig auf der Roadmap. Wie Sie sagen, zeichnen sich diese Tools durch ihre Einfachheit durch Abstraktion aus und haben viele Funktionen, die ich nicht in meiner Schicht haben möchte: Transaktionen, Sitzungen, L2-Caches usw. PS: Ist Ihre eigene Lösung gemeinfrei? Würde mich sehr interessieren!
Lukas Eder
8

"Es gibt eine Menge Wundermittel und es mangelt nicht an naiven Entwicklern."

Nichts für ungut, anscheinend verstehen Sie nicht ganz, was in diesem Bereich bereits gemacht wurde, und erfinden daher einige Räder neu. Die Erfahrung zeigt uns, dass die Räder, die Sie erfinden, zwar ordentlich und lustig, aber wahrscheinlich nicht annähernd so sind gut oder nützlich, da die schön raffinierten Räder bereits verfügbar sind.

Quentin-Starin
quelle
1
Vielen Dank für Ihr Feedback! Haben Sie sich meine Bibliothek genauer angesehen? Ich versuche genau, "das O aufzugeben", wie Ihr Artikel es nennt. jOOQ möchte, dass Entwickler SQL schreiben, nicht OR-Mapped-Code. Ich versuche zu erreichen, was Linq für .NET leistet, ohne den Java-Compiler neu schreiben zu können. Herzlichen Glückwunsch an Microsoft für Linq! Und ich wage zu sagen, dass ich nicht naiv bin, weil ich jOOQ erstellt habe, nachdem ich weder mit EJB 2.0 (vor einiger Zeit) noch mit Hibernate zufrieden war. Genau aus den Gründen, auf die Sie in Ihrem Artikel hinweisen. Ich habe versucht, was getan wurde und es entsprach nicht meinen Bedürfnissen.
Lukas Eder
jOOQ möchte, dass Entwickler Ihre kriterienähnliche API verwenden. Das ist kein SQL. Es ist eine Möglichkeit, SQL zu erstellen, die in Wirklichkeit hässlicher und komplizierter als SQL ist und nur sehr wenig oder gar keinen wirklichen Nutzen bringt. "q.addCompareCondition (TAuthor.YEAR_OF_BIRTH, 1920, Comparator.GREATER);" Ich sehe nichts wirklich anderes als jedes andere Tool zur Generierung von Klassen pro Tabelle. Das heißt, wie gesagt, es gibt mit ziemlicher Wahrscheinlichkeit bereits eine bessere. Von Vorlagen generierte Zeichenfolgenfelder kommen nicht einmal dem nahe, was Lambda-Ausdrücke ermöglichen.
Quentin-Star
1
Für mich ist es ein bisschen schwierig, die Motivation für Ihre Antwort / Ihren Kommentar zu verstehen. Ich denke immer noch, dass Sie sich die Beispiele, die ich zur Verfügung gestellt habe, nicht genau angesehen haben (Sie haben das allererste Beispiel zitiert), und Ihr Vergleich mit Konkurrenzprodukten erscheint mir etwas vage. Der Punkt meiner Frage war, konstruktives Feedback zu bekommen, und genau das würde ich begrüßen. Sie erwähnen "bessere Werkzeuge" und "Lambda-Ausdrücke". Könnten Sie bitte näher darauf eingehen? Wie vergleicht sich jOOQ mit den von Ihnen erwähnten Tools? Wie werden Lambda-Ausdrücke in Java 6 implementiert, bevor Oracle sie in Java 8 hinzufügen kann?
Lukas Eder
2

Ein Szenario, das diese Art von API geeignet macht, ist, wenn Sie einen datenbankunabhängigen SQL-Builder benötigen, den der Großteil des ORM nicht zulässt. Eine große Situation, in der ich sie gebraucht habe, ist die Erstellung von Berichten. Ich musste SQL objektorientiert erstellen und diese SQL zum Testen auf verschiedenen Datenbanken ausführen. Ruhezustand und anderes ORM sind sehr abhängig von Konfigurationen, was meine SQL-Konstruktion so einschränkt, dass ich keine Tabelle kombinieren kann, in der keine Zuordnung in den XML-Dateien vorhanden ist. Da im Berichtsmodul, das ich entwickle, jede Zuordnung möglich ist, hatte ich nach etwas anderem gesucht. Dann bin ich auf JOOQ gestoßen. Es löst nur mein Problem. Ich habe gerade einen Nur-Lese-Zugriff benötigt, stoße nie auf schmerzhafte Debugging-Probleme wie im Ruhezustand.

Eigentlich plane ich, eine andere Art der Datenmodellierung als die übliche POJO-Methode zu entwickeln und JOOQ als Grundlage für die Erstellung von SQL zu verwenden. Daher plane ich, zusätzlich zu JOOQ eine flexiblere Methode zum Modellieren von Daten / Entitäten mithilfe von HashMaps zu erstellen. Mein Design würde es ermöglichen, Front-End- und Back-End-Design leichter an einem Einstiegspunkt zu integrieren, obwohl ich verschiedene Ebenen verwenden würde, um das Framework zu vervollständigen, genau wie in den obigen Kommentaren angegeben. JOOQ wird wirklich eine sehr gute Rolle spielen, wie in meinem eigenen Projekt, es dient als eine der Grundlagen oder Säulen.

Also weiter so lukas gute Arbeit!

Ranke
quelle
1

Wenn ich Ihr Tool richtig verstehe, ordnet es Objekte direkt einem konzeptionellen SQL-Framework zu, anstatt Objekte zuzuordnen, die eine Zuordnung zu SQL-Funktionen (ORM) implementieren, fast wie eine ORM-Abstraktion für eine bessere geeky Kontrolle, sodass Sie mehr SQL-Funktionen verwenden können ORM's würden Sie normalerweise nicht geben?

Nicht sicher, welches Problem Sie lösen möchten. Da Ihr Tool fundierte SQL-Kenntnisse erfordert, würden die Leute dann nicht einfach SQL verwenden? Ist es der Klebercode, den Sie loswerden wollen? Bessere Validierung der SQL-Abfragen durch API-Modellierung anstelle einfacher Zeichenfolgen?

Ich muss zugeben, dass Ihre JOOQ-Beispiele wie LISP-Versionen von SQL aussehen. Nicht, dass das eine schlechte Sache ist :) und ich sehe, dass einige der fortgeschrittenen Dinge interessant sind, aber die Vorteile, die Sie auflisten, verschwinden langsam, wenn Sie fortschrittlicher werden (mehr Konfiguration, weniger abstrakt, tiefer verwurzelt im Inneren des spezifischen SQL Motor usw.)

Ein Vorschlag, den ich in den meisten ORMs vermissen möchte, ist ein Framework, das mit Objekten in nicht relationaler Weise umgehen kann und Objektinteraktionen in jedes beliebige Backend (SQL, NoSQL, Topic Maps, RDF usw.) Übersetzt .), für die das verwendete Modell zwischengespeichert werden muss und nicht die Besonderheiten von SQL-Interaktionen, Dialekten und relationalem Denken.

IMHO natürlich. :)

AlexanderJohannesen
quelle
Hallo, danke für dein Feedback. Du hast es richtig. Wie Qstarin es ausdrückte, versuche ich, das "O" aus ORM zu entfernen und relational zu bleiben. Warum nicht einfach SQL? Du meinst JDBC? Haben Sie jemals Ihre Datenbank mit 5 verschachtelten Auswahlen und mehreren Verknüpfungen, Analysefunktionen mit JDBC, abgefragt? Syntaxfehler, Bindungsinkongruenzen usw. Leider kann jOOQ nicht das richtige Tool für Sie sein, da es keine Möglichkeit gibt, ein beliebiges Modell Objekten zuzuordnen . Und das will ich nicht. jOOQ sollten relational sein. Für diejenigen Entwickler, die diese Denkweise bevorzugen. Für die anderen empfehle ich JPA. Oder Linq, wenn du .NET machst
Lukas Eder