Ich habe eine Java-Swing-Anwendung mit einem Thick-Client mit einem Schema von 25 Tabellen und ~ 15 JInternalFrames (Dateneingabeformulare für die Tabellen). Ich muss für die DBMS-Interaktion eine Entwurfsauswahl für gerades JDBC oder ORM (in diesem Fall Ruhezustand mit Federrahmen) treffen. Das Erstellen aus der Anwendung wird in Zukunft erfolgen.
Wäre der Winterschlaf für ein Projekt dieser Größe übertrieben? Eine Erklärung der Antwort mit Ja oder Nein wäre sehr willkommen (oder sogar ein anderer Ansatz, wenn dies gerechtfertigt ist).
TIA.
Antworten:
Gute Frage ohne einfache Antwort.
Ich war ein großer Fan von Hibernate, nachdem ich es über mehrere Jahre in mehreren Projekten verwendet hatte. Früher war ich der Meinung, dass jedes Projekt standardmäßig in den Ruhezustand versetzt werden sollte.
Heute bin ich mir nicht so sicher.
Hibernate (und JPA) eignen sich hervorragend für einige Dinge, insbesondere zu Beginn des Entwicklungszyklus. Es ist viel schneller, mit Hibernate zu arbeiten, als mit JDBC. Sie erhalten viele Funktionen zum kostenlosen Caching, zum optimistischen Sperren und so weiter.
Auf der anderen Seite hat es einige versteckte Kosten. Der Ruhezustand ist zu Beginn täuschend einfach . Befolgen Sie ein Tutorial, fügen Sie Ihrer Klasse einige Anmerkungen hinzu - und Sie haben Ausdauer. Aber es ist nicht einfach und um guten Code darin schreiben zu können, muss man sowohl die internen Abläufe als auch das Datenbankdesign gut verstehen. Wenn Sie gerade erst anfangen, sind Ihnen möglicherweise einige Probleme nicht bekannt, die Sie später beißen könnten. Hier ist eine unvollständige Liste.
Performance
Die Laufzeitleistung ist gut genug, ich habe noch keine Situation gesehen, in der der Ruhezustand der Grund für die schlechte Leistung in der Produktion war . Das Problem ist die Startleistung und wie sie sich auf die Zeit und die Entwicklungsleistung Ihrer Unit-Tests auswirkt. Wenn der Ruhezustand geladen wird, werden alle Entitäten analysiert und viele Vor-Caching-Vorgänge ausgeführt. Bei einer nicht sehr großen Anwendung kann dies etwa 5-10-15 Sekunden dauern. Ihr 1-Sekunden-Unit-Test dauert also jetzt 11 Sekunden. Kein Spaß.
Datenbankunabhängigkeit
Es ist sehr cool, solange Sie keine Feinabstimmung an der Datenbank vornehmen müssen.
In-Memory-Sitzung
Für jede Transaktion speichert Hibernate ein Objekt im Speicher für jede Datenbankzeile, die es "berührt". Es ist eine schöne Optimierung, wenn Sie eine einfache Dateneingabe vornehmen. Wenn Sie jedoch aus irgendeinem Grund viele Objekte verarbeiten müssen, kann dies die Leistung erheblich beeinträchtigen, es sei denn, Sie bereinigen die In-Memory-Sitzung explizit und sorgfältig selbst.
Kaskaden
Mit Kaskaden können Sie die Arbeit mit Objektdiagrammen vereinfachen. Wenn Sie beispielsweise ein Stammobjekt und einige untergeordnete Objekte haben und das Stammobjekt speichern, können Sie den Ruhezustand so konfigurieren, dass auch untergeordnete Objekte gespeichert werden. Das Problem beginnt, wenn Ihr Objektdiagramm komplexer wird. Wenn Sie nicht äußerst vorsichtig sind und ein gutes Verständnis dafür haben, was intern vor sich geht, ist es leicht, dies durcheinander zu bringen. Und wenn Sie dies tun, ist es sehr schwierig, diese Probleme zu beheben.
Faules Laden
Lazy Loading bedeutet, dass der Ruhezustand jedes Mal, wenn Sie ein Objekt laden, nicht alle zugehörigen Objekte lädt, sondern Platzhalter bereitstellt, die aufgelöst werden, sobald Sie versuchen, auf sie zuzugreifen. Tolle Optimierung, oder? Es ist so, außer dass Sie sich dieses Verhaltens bewusst sein müssen, sonst erhalten Sie kryptische Fehler. Google "LazyInitializationException" für ein Beispiel. Und seien Sie vorsichtig mit der Leistung. Abhängig von der Reihenfolge, in der Sie Ihre Objekte und Ihr Objektdiagramm laden, können Sie auf "n + 1 wählt Problem aus" klicken. Google es für weitere Informationen.
Schema-Upgrades
Der Ruhezustand ermöglicht einfache Schemaänderungen, indem nur Java-Code umgestaltet und neu gestartet wird. Es ist großartig, wenn Sie anfangen. Aber dann veröffentlichen Sie Version eins. Und wenn Sie Ihre Kunden nicht verlieren möchten, müssen Sie ihnen Schema-Upgrade-Skripte bereitstellen. Dies bedeutet kein einfacheres Refactoring mehr, da alle Schemaänderungen in SQL durchgeführt werden müssen.
Ansichten und gespeicherte Prozeduren
Für den Ruhezustand ist exklusiver Schreibzugriff auf die Daten erforderlich, mit denen er arbeitet. Dies bedeutet, dass Sie Ansichten, gespeicherte Prozeduren und Trigger nicht wirklich verwenden können, da diese Änderungen an Daten verursachen können, deren Ruhezustand sie nicht kennt. Einige externe Prozesse können Daten in separaten Transaktionen in die Datenbank schreiben. In diesem Fall enthält Ihr Cache jedoch ungültige Daten. Welches ist eine weitere Sache, um die man sich kümmern muss.
Single Threaded Sessions
Sitzungen im Ruhezustand sind Single-Threaded-Sitzungen. Auf jedes Objekt, das über eine Sitzung geladen wurde, kann nur von demselben Thread aus zugegriffen werden (einschließlich Lesen). Dies ist für serverseitige Anwendungen akzeptabel, kann jedoch unnötige Probleme verursachen, wenn Sie eine GUI-basierte Anwendung ausführen.
Ich denke mein Punkt ist, dass es keine kostenlosen Mahlzeiten gibt.
Der Ruhezustand ist ein gutes Werkzeug, aber es ist ein komplexes Werkzeug, und es erfordert Zeit, um es richtig zu verstehen. Wenn Sie oder Ihre Teammitglieder nicht über solche Kenntnisse verfügen, ist es möglicherweise einfacher und schneller, für eine einzelne Anwendung reines JDBC (oder Spring JDBC) zu verwenden. Wenn Sie jedoch bereit sind, Zeit in das Lernen zu investieren (einschließlich Learning by Doing und Debugging), können Sie die Kompromisse in Zukunft besser verstehen.
quelle
Der Ruhezustand kann gut sein, aber er und andere JPA-ORMs bestimmen in der Regel Ihre Datenbankstruktur bis zu einem gewissen Grad. Zusammengesetzte Primärschlüssel können beispielsweise in Hibernate / JPA erstellt werden, sind jedoch etwas umständlich. Es gibt andere Beispiele.
Wenn Sie mit SQL vertraut sind, empfehle ich Ihnen dringend, sich Ibatis anzusehen . Es kann über 90% dessen leisten, was Hibernate kann, ist jedoch in der Implementierung weitaus einfacher.
Ich kann mir keinen einzigen Grund vorstellen, warum ich jemals JDBC (oder sogar Spring JDBC) anstelle von Ibatis gewählt habe. Der Ruhezustand ist eine komplexere Wahl.
Schauen Sie sich das Spring and Ibatis Tutorial an .
quelle
Zweifellos hat der Ruhezustand seine Komplexität.
Aber was ich am Hibernate-Ansatz (einige andere auch) wirklich mag, ist das konzeptionelle Modell, das Sie in Java erhalten können, ist besser. Obwohl ich OO nicht als Allheilmittel betrachte und nicht nach theoretischer Reinheit des Designs suche, habe ich so oft festgestellt, dass OO meinen Code tatsächlich vereinfacht. Da Sie speziell nach Details gefragt haben, sind hier einige Beispiele:
Die zusätzliche Komplexität ist nicht im Modell enthalten und Entitäten, sondern in Ihrem Framework, um beispielsweise alle Entitäten zu manipulieren. Für Betreuer besteht der schwierige Teil nicht aus wenigen Framework-Klassen, sondern aus Ihrem Modell. Mit Hibernate können Sie den schwierigen Teil (das Modell) auf dem saubersten Stand halten.
Wenn in all Ihren Entitäten ein Feld (wie eine ID oder Überwachungsfelder usw.) verwendet wird, können Sie damit eine Oberklasse erstellen . Deshalb :
Der Ruhezustand bietet auch viele Funktionen, um mit anderen Modellmerkmalen umzugehen, die Sie möglicherweise benötigen (jetzt oder später fügen Sie sie nur nach Bedarf hinzu). Nehmen Sie es als Erweiterungsqualität für Ihr Design.
Bei der Wiederverwendung zwischen Ihren Entitäten (jedoch nur bei angemessener Vererbung und Zusammensetzung ) ergeben sich normalerweise einige zusätzliche Vorteile. Beispiele:
Im Laufe der Zeit entwickeln sich die Anforderungen. Es wird einen Punkt geben, an dem Ihre Datenbankstruktur Probleme hat. Nur mit JDBC muss sich jede Änderung an der Datenbank auf den Code auswirken (dh doppelte Kosten). In Hibernate können viele Änderungen übernommen werden, indem nur die Zuordnung und nicht der Code geändert wird. Das Gleiche passiert umgekehrt: Im Ruhezustand können Sie Ihren Code (z. B. zwischen Versionen) ändern, ohne Ihre Datenbank zu ändern (die Zuordnung zu ändern, obwohl dies nicht immer ausreicht). Zusammenfassend lässt sich sagen, dass Sie mit Hibernate Ihre Datenbank und Ihren Code unabhängig voneinander weiterentwickeln können .
Aus all diesen Gründen würde ich Hibernate wählen :-)
quelle
Ich denke, beides ist eine gute Wahl, aber ich persönlich würde den Ruhezustand verwenden. Ich denke nicht, dass der Ruhezustand für ein Projekt dieser Größe übertrieben ist.
Wo Hibernate für mich wirklich glänzt, ist der Umgang mit Beziehungen zwischen Entitäten / Tabellen. Das manuelle Ausführen von JDBC kann viel Code erfordern, wenn Sie Eltern und Kinder (Enkelkinder, Geschwister usw.) gleichzeitig ändern. Der Ruhezustand kann dies zu einem Kinderspiel machen (häufig reicht ein einziges Speichern der übergeordneten Entität aus).
Es gibt jedoch sicherlich Komplexitäten beim Umgang mit dem Ruhezustand, z. B. das Verständnis der Funktionsweise des Sitzungsspülens und das langsame Laden.
quelle
Straight JDBC würde bestenfalls in die einfachsten Fälle passen.
Wenn Sie in Java und OOD bleiben möchten, sollten Sie sich für Hibernate oder Hibernate / JPA oder einen anderen JPA-Anbieter / JPA entscheiden.
Wenn Sie mit SQL besser vertraut sind, schadet es nicht, Spring for JDBC-Vorlagen und andere SQL-orientierte Frameworks zu haben.
Im Gegensatz dazu hilft Spring neben der Transaktionskontrolle nicht viel, wenn Sie mit JPA arbeiten.
quelle
Der Ruhezustand eignet sich am besten für Middleware-Anwendungen. Angenommen, wir bauen eine Middleware auf der Datenbank auf. Auf die Mittelware wird von etwa 20 Anwendungen zugegriffen. In diesem Fall können wir einen Ruhezustand haben, der die Anforderungen aller 20 Anwendungen erfüllt.
quelle
Wenn wir in JDBC eine Datenbankverbindung öffnen, müssen wir in try schreiben, und wenn Ausnahmen aufgetreten sind, wird catch block dies tun und schließlich zum Schließen der Verbindungen verwendet.
In jdbc sind alle Ausnahmen geprüfte Ausnahmen, daher müssen wir Code in try, catch und throw schreiben, aber im Ruhezustand haben wir nur nicht geprüfte Ausnahmen
Hier müssen wir als Programmierer die Verbindung schließen, sonst haben wir möglicherweise die Möglichkeit, unsere Verbindungsnachricht zu erhalten…!
Wenn wir die Verbindung im finally-Block nicht geschlossen haben, ist jdbc nicht dafür verantwortlich, diese Verbindung zu schließen.
In JDBC müssen wir SQL-Befehle an verschiedenen Stellen schreiben. Nachdem das Programm erstellt wurde, wenn die Tabellenstruktur geändert wurde, funktioniert das JDBC-Programm nicht. Auch hier müssen wir die erforderlichen Änderungen ändern, kompilieren und erneut bereitstellen, was mühsam ist.
JDBC wird verwendet, um datenbankbezogene Fehlercodes zu generieren, wenn eine Ausnahme auftritt. Java-Programmierer kennen diese Fehlercodes jedoch nicht.
Wenn wir beim Einfügen eines Datensatzes keine bestimmte Tabelle in der Datenbank haben, löst JDBC einen Fehler wie "Ansicht nicht vorhanden" aus und löst eine Ausnahme aus. Im Ruhezustand wird jedoch keine Tabelle in der Datenbank gefunden Datenbank erstellt dies die Tabelle für uns
JDBC unterstützt das Laden von LAZY und Hibernate unterstützt das Laden von Eager
Der Ruhezustand unterstützt Vererbung, Zuordnungen, Sammlungen
Wenn wir im Ruhezustand das abgeleitete Klassenobjekt speichern, wird auch sein Basisklassenobjekt in der Datenbank gespeichert. Dies bedeutet, dass der Ruhezustand die Vererbung unterstützt
Der Ruhezustand unterstützt Beziehungen wie Eins-zu-viele, Eins-zu-eins, viele-zu-viele-zu-viele, viele-zu-eins
Der Ruhezustand unterstützt den Caching-Mechanismus, wodurch die Anzahl der Roundtrips zwischen einer Anwendung und der Datenbank verringert wird. Durch Verwendung dieser Caching-Technik wird die Anwendungsleistung automatisch erhöht
Paginierung im Winterschlaf zu bekommen ist ganz einfach.
Im Ruhezustand können Primärschlüssel automatisch generiert werden, während die Datensätze in einer Datenbank gespeichert werden
quelle
Sie könnten sich Ebean ORM ansehen, das keine Sitzungsobjekte verwendet ... und bei dem das verzögerte Laden einfach funktioniert. Sicherlich eine Option, kein Overkill, und wird einfacher zu verstehen sein.
quelle
Wenn Milliarden von Benutzern die App oder das Web verwenden, wird die Abfrage in jdbc milliardenfach ausgeführt, aber im Ruhezustand wird die Abfrage nur einmal für eine beliebige Anzahl von Benutzern ausgeführt, der wichtigste und einfachste Vorteil des Ruhezustands gegenüber jdbc.
quelle