Java-Programmierung - Wo sollen SQL-Anweisungen gespeichert werden? [geschlossen]

106

Wo sollte eine JDBC-kompatible Anwendung ihre SQL-Anweisungen speichern und warum?

Bisher konnte ich folgende Optionen identifizieren:

  • In Geschäftsobjekten fest codiert
  • Eingebettet in SQLJ Klauseln
  • In getrennten Klassen einkapseln, z Datenzugriffsobjekte
  • Metadatengesteuert (entkoppeln Sie das Objektschema vom Datenschema - beschreiben Sie die Zuordnungen zwischen ihnen in Metadaten)
  • Externe Dateien (z. B. Eigenschaften- oder Ressourcendateien)
  • Gespeicherte Prozeduren

Was sind die Vor- und Nachteile für jeden einzelnen?

Sollte SQL-Code als "Code" oder "Metadaten" betrachtet werden?

Sollten gespeicherte Prozeduren nur zur Leistungsoptimierung verwendet werden oder sind sie eine legitime Abstraktion der Datenbankstruktur?

Ist Leistung ein Schlüsselfaktor für die Entscheidung? Was ist mit der Lieferantenbindung ?

Was ist besser - lose oder enge Kupplung und warum?

EDITED: Vielen Dank an alle für die Antworten - hier ist eine Zusammenfassung:

Metadatengesteuert, dh Object Relational Mappings (ORM)

Vorteile:

  • Sehr abstrakt - Der DB-Server kann gewechselt werden, ohne dass das Modell geändert werden muss
  • Weit verbreitet - praktisch ein Standard
  • Reduziert die Menge an benötigtem SQL
  • Kann SQL in Ressourcendateien speichern
  • Leistung ist (normalerweise) akzeptabel
  • Metadatengetriebener Ansatz
  • Herstellerunabhängigkeit (Datenbank)

Nachteile:

  • Versteckt SQL und echte Entwicklerabsichten
  • SQL kann vom DBA nur schwer überprüft / geändert werden
  • In ungeraden Fällen wird möglicherweise noch SQL benötigt
  • Kann die Verwendung einer proprietären Abfragesprache erzwingen, z. B. HQL
  • Geeignet nicht zur Optimierung (Abstraktion)
  • Kann referenzielle Integrität fehlen
  • Ersatz für mangelnde SQL-Kenntnisse oder mangelnde Sorgfalt beim Codieren in der Datenbank
  • Passen Sie niemals die native Datenbankleistung an (auch wenn sie nahe kommt).
  • Der Modellcode ist sehr eng mit dem Datenbankmodell gekoppelt

Hardcodiert / eingekapselt in DAO-Schicht

Vorteile:

  • SQL wird in den Objekten gespeichert, die auf Daten zugreifen (Kapselung)
  • SQL ist einfach zu schreiben (Entwicklungsgeschwindigkeit)
  • SQL ist leicht zu finden, wenn Änderungen erforderlich sind
  • Einfache Lösung (keine chaotische Architektur)

Nachteile:

  • SQL kann vom DBA nicht überprüft / geändert werden
  • SQL wird wahrscheinlich DB-spezifisch
  • SQL kann schwer zu warten sein

Gespeicherte Prozeduren

Vorteile:

  • SQL in der Datenbank gespeichert (in der Nähe von Daten)
  • SQL wird vom DBMS analysiert, kompiliert und optimiert
  • SQL kann von DBA leicht überprüft / geändert werden
  • Reduziert den Netzwerkverkehr
  • Erhöhte Sicherheit

Nachteile:

  • SQL ist an die Datenbank gebunden (Vendor Lock-In).
  • SQL-Code ist schwieriger zu pflegen

Externe Dateien (z. B. Eigenschaften- oder Ressourcendateien)

Vorteile

  • SQL kann geändert werden, ohne dass die Anwendung neu erstellt werden muss
  • Entkoppelt die SQL-Logik von der Geschäftslogik der Anwendung
  • Zentrales Repository aller SQL-Anweisungen - einfacher zu warten
  • Leichter zu verstehen

Nachteile:

  • SQL-Code kann nicht mehr wartbar sein
  • Es ist schwieriger, den SQL-Code auf (Syntax-) Fehler zu überprüfen

Eingebettet in SQLJ-Klauseln

Vorteile:

  • Bessere Syntaxprüfung

Nachteile:

  • Bindet zu eng an Java
  • Geringere Leistung als JDBC
  • Fehlende dynamische Abfragen
  • Nicht so beliebt
Adrian
quelle
Gute Fragen, aber vielleicht etwas zu viel, um sie auf einmal zu beantworten. Es würde ein paar Seiten dauern, um all diese Fragen zu beantworten: p
NickDK
+1 Gute Frage! Sie sollten "ORM" pro @ocdecio hinzufügen. Fügen Sie außerdem "überall in Ihrem Java-Code verteilt" hinzu (was ich gesehen habe und das Schlimmste sein muss).
Jim Ferrans
2
Ich bin nicht einverstanden mit "SQL-Code ist schwieriger zu pflegen" unter "Gespeicherte Prozeduren". In meinem XP war SQL einfacher zu warten, sobald es in die Datenbank ging. Teilweise aus einem Grund, der in externen Dateien verwendet wird (zentrales Repository aller SQL-Anweisungen - einfacher zu warten), und die Parameter sind einfacher zu verwalten.
Michael Lloyd Lee mlk
1
Meiner Meinung nach haben Sie eine Option verpasst: Die Verwendung von Ansichten. Sie können komplexes SQL in Ansichten ausdrücken und dann einfach einfache Auswahlen in diesen Ansichten ausdrücken (unter Verwendung einer beliebigen Art von Abstraktion: DAO, SQLJ, ORMs usw.). Sie werden ähnliche Vorteile haben wie bei gespeicherten Prozeduren, aber ich glaube nicht, dass Sie irgendwelche Nachteile haben werden ...
Lukas Eder

Antworten:

31

Je größer die Anwendung in Bezug auf Größe und / oder Wiederverwendbarkeit ist, desto mehr müssen normalerweise die SQL-Anweisungen externalisiert / abstrahiert werden.

Hardcodiert (als statische Endkonstanten) ist der erste Schritt. Das Speichern in einer Datei (Eigenschaften / XML-Datei) ist der nächste Schritt. Metadatengesteuert (wie von einem ORM wie Hibernate / JPA ausgeführt) ist der letzte Schritt.

Hardcoded hat den Nachteil, dass Ihr Code wahrscheinlich DB-spezifisch wird und Sie bei jeder Änderung neu schreiben / neu erstellen / neu verteilen müssen. Vorteil ist, dass Sie es an 1 Stelle haben.

Das Speichern in einer Datei hat den Nachteil, dass sie beim Wachsen der Anwendung nicht mehr gewartet werden kann. Vorteil ist, dass Sie die App nicht neu schreiben / erstellen müssen, es sei denn, Sie müssen eine zusätzliche DAO-Methode hinzufügen.

Metadatengesteuert hat den Nachteil, dass Ihr Modellcode sehr eng mit dem Datenbankmodell gekoppelt ist. Für jede Änderung im Datenbankmodell müssen Sie den Code neu schreiben / neu erstellen / neu verteilen. Der Vorteil ist, dass es sehr abstrakt ist und dass Sie problemlos vom DB-Server wechseln können, ohne Ihr Modell ändern zu müssen (aber fragen Sie sich jetzt: Wie oft würde ein Unternehmen vom DB-Server wechseln? Wahrscheinlich nur einmal pro 3 Jahre, nicht wahr?) t es?).

Ich werde gespeicherte Prozeduren dafür nicht als "gute" Lösung bezeichnen. Sie haben einen ganz anderen Zweck. Auch wenn Ihr Code von der verwendeten Datenbank / Konfiguration abhängt.

BalusC
quelle
21

Ich weiß nicht, ob dies optimal ist, aber meiner Erfahrung nach werden sie in der DAO-Ebene fest codiert (dh String-Literale).

Flybywire
quelle
5
Es ist wahrscheinlich nicht optimal, aber ich mache es auch. Einfach zu schreiben, leicht zu finden und keine unordentliche Architektur, über die man sich Sorgen machen muss.
James Cronen
21
Die gesamte Zeit, die für die Suche nach fest codiertem SQL aufgewendet wird, ist die Arbeitsplatzsicherheit. Wenn Sie die einzige Person sind, die weiß, wo sich SQL befindet, können Sie nicht entlassen werden.
S.Lott
11
Es wundert mich immer wieder, dass viele Leute, die darauf achten, gut strukturierten, sauberen OO-Java-Code zu erstellen, dieselben Leute sind, die es tolerieren, unordentliches, nicht performantes SQL zu schreiben und es einfach als Zeichenfolgen an zufälligen Stellen festzuhalten. Wenn Ihr SQL nur Zeichenfolgen in Ihrer DAO-Schicht sind, kann ich so ziemlich garantieren, dass Sie keinen DBA in Ihrem Team haben. Zumindest kein guter DBA.
Daniel Pryden
3
-1. Es ist in Ordnung, DAOs zu haben, aber verschieben Sie die Abfragen zumindest in eine Eigenschaftendatei, damit ein DBA sie überprüfen und gegebenenfalls optimieren kann!
Cethegeek
3
Ich habe die Erfahrung gemacht, dass das Einfügen der Abfragezeichenfolge in eine Datenzugriffsobjektebene wahrscheinlich der beste Ansatz ist, wenn Sie keine ORM-Lösung verwenden können, wenn Sie direkt JDBC ausführen. Sobald dies eine Einschränkung ist, stellen Sie sicher, dass alle auf derselben Seite Codierungsstandards für die DAO-Klassen haben, wenn Sie diesen Weg gehen. Ich habe sowohl die Routen für Ressourcenpakete als auch für gespeicherte Prozeduren heruntergefahren und beide waren absolute Albträume bei der Wartung, da sie die Datenzugriffslogik auf mehrere Ebenen verteilen. Wenn Sie also einer Abfrage eine Spalte hinzufügen, müssen Sie die Dinge an verschiedenen Stellen ändern.
Jason Gritman
12

Ich glaube nicht, dass Ihnen jemand die gewünschte Pro / Contra-Aufschlüsselung geben wird, da dies eine ziemlich große Frage ist. Stattdessen ist hier, was ich in der Vergangenheit verwendet habe und was ich in Zukunft verwenden werde.

Ich verwende SQL, das im DAL fest codiert ist. Ich fand das in Ordnung, bis die Datenbankadministratoren mit SQL spielen wollten. Dann müssen Sie es ausgraben, formatieren und an die Datenbankadministratoren weiterleiten. Wer wird darüber lachen und alles ersetzen. Aber ohne die schönen Fragezeichen oder die Fragezeichen in der falschen Reihenfolge und lassen Sie es zurück in den Java-Code.

Wir haben auch ein ORM verwendet, und obwohl dies für Entwickler großartig ist, haben unsere Datenbankadministratoren es gehasst, da es kein SQL gibt, über das sie lachen können. Wir haben auch ein ungerades ORM verwendet (ein benutzerdefiniertes ORM von einem Drittanbieter), das die Gewohnheit hatte, die Datenbank zu töten. Ich habe JPA seitdem verwendet und war großartig, aber es ist ein harter Kampf, etwas Kompliziertes hinter den DBAs zu bekommen.

Wir verwenden jetzt gespeicherte Prozeduren (wobei die Aufrufanweisung fest codiert ist). Das erste, worüber sich jeder beschweren wird, ist, dass Sie an die Datenbank gebunden sind. Du bist. Wie oft haben Sie jedoch die Datenbank geändert? Ich weiß, dass wir es einfach nicht einmal versuchen konnten, die Menge an anderem Code, die davon abhängt, sowie die Umschulung unserer Datenbankadministratoren und die Migration der Daten. Es wäre eine sehr teure Operation. Wenn jedoch in Ihrer Welt das Ändern von DBs im Handumdrehen erforderlich ist, sind SPs wahrscheinlich nicht verfügbar.

In Zukunft möchte ich gespeicherte Prozeduren mit Tools zur Codegenerierung verwenden, um Java-Klassen aus Oracle-Paketen zu erstellen.

Edit 2013-01-31 : Ein paar Jahre und DBAs später und wir verwenden jetzt Hibernate und gehen nur dann zu SQL (gespeicherte Prozesse in der DB), wenn dies unbedingt erforderlich ist. Dies ist meiner Meinung nach die beste Lösung. In 99% der Fälle müssen sich die DBs keine Gedanken über SQL machen, und die 1%, die sie tun, befinden sich an einem Ort, mit dem sie bereits vertraut sind.

Michael Lloyd Lee mlk
quelle
1
+1 für die Idee, gespeicherte Prozeduren zu schreiben und dann Java-Code daraus zu generieren, nicht umgekehrt.
Daniel Pryden
Ich gehe davon aus, dass die Java-Ebene die DB-Ebene NICHT in irgendeiner Weise nachahmen oder zuordnen sollte. Ich denke, wenn Sie versuchen, das Oracle-Paket zu abstrahieren, dann machen Sie ein anderes Paket oder mehr Wrapping-Verfahren. Ich versuche, die beiden durch Übung logisch vollständig zu trennen.
Jé Queue
2
@Xepoch: Ich stimme tatsächlich zu - vielleicht hätte ich meinen Kommentar anders formulieren sollen. Ihre Datenbank sollte ein Spiegelbild Ihres Datenmodells sein (Entity Relationship Model), und Ihr Objektmodell sollte auch ein Spiegelbild Ihres Datenmodells sein (obwohl nicht unbedingt identisch). Sie sollten also zumindest verwandt sein. Beim Generieren von Java-Code aus gespeicherten Prozeduren sollte die API für den Zugriff auf Ihre Datenbank aus der Struktur Ihres Datenmodells abgeleitet werden, nicht Ihr Datenmodell aus der Struktur Ihrer Objekte.
Daniel Pryden
Möglicherweise möchten Sie jooq.org verwenden . Es macht genau das, was Sie gesagt haben: "Codegenerierung zum Erstellen von Java-Klassen aus Oracle-Paketen". Abgesehen davon wird es mit einem SQL-ähnlichen DSL geliefert, ähnlich wie LINQ in C #, falls Sie SQL in Java ausdrücken müssen, das Sie nicht in eine gespeicherte Prozedur einfügen können.
Lukas Eder
10

Wenn Sie ein ORM (z. B. den Ruhezustand) verwenden, müssen Sie sich hoffentlich keine Sorgen um SQL-Anweisungen machen. Die Leistung ist normalerweise akzeptabel und Sie erhalten auch Herstellerunabhängigkeit.

Otávio Décio
quelle
13
-1 Sie haben HQL-Anweisungen und die meisten Probleme bleiben in Bezug auf HQL bestehen. Befinden sie sich im Code (Zeichenfolgenliterale), benannte Abfragen in Anmerkungen, benannte Abfragen in XML-Dateien, die in Eigenschaftendateien gespeichert sind?
Flybywire
1
@flybywire - mit Hibernate ist es eine Seltenheit, auf HQL zurückzugreifen. In 98% der Fälle ist nur eine Abfrage nach Beispiel und nach Kriterien (dh Verwendung von Objekten) erforderlich.
SingleShot
2
@ SingleShot, ich stimme nicht zu. Wenn es etwas komplexer als Auswahl von id ist, ich denke , es wird mit HQL getan. Ich würde sagen, Kriterien und Beispiele werden verwendet, wenn eine benutzeroberflächengesteuerte Suche wie in einem Suchbildschirm in einem Bibliothekskatalog durchgeführt wird. Aber mal sehen, was andere denken.
Flybywire
3
@ SingleShot - Ich bin sehr anderer Meinung. Wir verwenden viel HQL, insbesondere zum Melden von Abfragen. Einige HQL-Funktionen wurden von Kriterien überhaupt nicht unterstützt (unter Verwendung benutzerdefinierter SQL-Funktionen, Konstruktoren in der Select-Klausel). QBE kann manchmal zu mehr Problemen führen, als es löst.
Javashlook
4
"Mit Hibernate ist es eine Seltenheit, auf HQL zurückzugreifen" ist bei weitem das lustigste, was ich heute gehört habe. QBE ist lächerlich; und während Sie möglicherweise auf Kriterien für UI-Abfragen zurückgreifen müssen , sollten genau definierte Abfragen (Berichterstellung / Serviceinteraktion / etc ...) alle in HQL enthalten sein.
ChssPly76
10

Sollte SQL-Code als "Code" oder "Metadaten" betrachtet werden?

Code.

Sollten gespeicherte Prozeduren nur zur Leistungsoptimierung verwendet werden oder sind sie eine legitime Abstraktion der Datenbankstruktur?

Gespeicherte Prozeduren ermöglichen die Wiederverwendung, auch innerhalb anderer gespeicherter Prozeduren. Dies bedeutet, dass Sie eine Reise in die Datenbank unternehmen und unterstützende Anweisungen ausführen lassen können - das geringste Verkehrsaufkommen ist ideal. ORM oder sproc, die Zeit auf dem Draht zur Datenbank und zurück ist etwas, das Sie nicht wieder gutmachen können.

ORM eignet sich aufgrund seiner Abstraktion nicht zur Optimierung. IME, ORM bedeutet auch einen Mangel an referenzieller Integrität - erschweren die Berichterstattung über eine Datenbank. Was an Komplexität gespart wurde, hat jetzt zugenommen, um die Daten auf funktionsfähige Weise herausholen zu können.

Ist Leistung ein Schlüsselfaktor für die Entscheidung? Was ist mit der Lieferantenbindung?

Nein, Einfachheit ist. Die Lieferantenbindung erfolgt auch mit der Datenbank - SQL ist relativ standardisiert, es gibt jedoch immer noch herstellerspezifische Methoden.

OMG Ponys
quelle
4
+1 zum Aufrufen von SQL-Code. Zu viele ORM-Tools versuchen, SQL zu verbergen, obwohl dies häufig die beste Sprache ist, um auszudrücken, was Sie tun möchten. Und ich stimme Ihrer Meinung zu, dass gespeicherte Prozeduren besser sind als ORM, obwohl ich bezweifle, dass dies hier eine beliebte Meinung sein wird.
Daniel Pryden
9

Interessant ist die Angst vor einer Lieferantenbindung in der Java-Welt.

Ich hoffe, Sie haben nicht 50000 US-Dollar pro CPU für Oracle Enterprise bezahlt und dann nur den kleinsten gemeinsamen Nenner verwendet, um jede Minute zu MySQL zu wechseln. Wie jeder gute DBA Ihnen sagen wird, gibt es subtile Unterschiede zwischen den verschiedenen namhaften Datenbanken, insbesondere in Bezug auf Sperrmodelle und wie sie Konsistenz erreichen.

Treffen Sie also keine Entscheidung darüber, wie Sie Ihre SQL-Aufrufe nur nach dem Prinzip des herstellerunabhängigen SQL implementieren - haben Sie einen echten (geschäftlichen) Grund dafür.

Hennings
quelle
1
Oh, nichts dergleichen! Das Hauptanliegen besteht darin, dem Support-Team zu ermöglichen, SQL-Anweisungen zu ändern (z. B. für Optimierungen, DBA-bezogene Aufgaben) und die Sichtbarkeit der Anwendung der Anwendung (in Bezug auf die Datenbank) zu verbessern. Das Support-Team verfügt nicht über Java-Know-how und wird dies auch nicht tun Schauen Sie sich den Code genauer an. Die Anwendung wird eine neue Ergänzung zu einem großen Bestand bestehender Anwendungen sein, die alle eine Ingres-Datenbank verwenden.
Adrian
6

SQL in gespeicherten Prozeduren wird vom Datenbanksystem optimiert und auf Geschwindigkeit kompiliert - das ist seine natürliche Heimat. SQL wird vom Datenbanksystem verstanden und vom Datenbanksystem analysiert. Behalten Sie Ihre SQL in der Datenbank, wenn Sie können; Wickeln Sie es in gespeicherte Prozeduren oder Funktionen oder in die vom Datenbanksystem bereitgestellten Logikeinheiten ein und rufen Sie es einfach mit einem der von Ihnen oder anderen genannten Tools auf.

Warum SQL-Code für das Datenbanksystem außerhalb der Datenbank speichern? Oft aus Gründen der Entwicklungsgeschwindigkeit. Warum ORM-Mapping verwenden? - Einige sagen, dass die ORM-Zuordnung Kompatibilität zwischen verschiedenen Datenbanksystemen bietet. In der realen Welt verlagert sich eine Anwendung jedoch selten von der Datenbankplattform, auf der sie erstellt wurde, insbesondere wenn erweiterte Funktionen wie die Replikation verwendet werden. In den seltenen Fällen, in denen das Datenbanksystem ausgetauscht wird, sind einige Arbeiten erforderlich . Ich glaube, einer der Nachteile von ORM ersetzt häufig mangelnde SQL-Kenntnisse oder mangelnde Sorgfalt beim Codieren in der Datenbank. Außerdem wird ORM niemals mit der Leistung nativer Datenbanken übereinstimmen, selbst wenn es nahe kommt.

Ich stehe auf der Seite, SQL-Code in der Datenbank zu behalten und ihn über eine beliebige API oder Schnittstelle, die Sie verwenden möchten, einfach aufzurufen. Abstraktieren Sie auch den Punkt, an dem Ihre Datenbankaufrufe getätigt werden, indem Sie diese Aufrufe hinter eine abstrakte Klasse oder OO-Schnittstelle stellen (ausgedrückt durch Methoden). Wenn Sie also jemals eine neue Art von Datenquelle austauschen, ist diese nahtlos mit der Geschäftsschicht verbunden .

John K.
quelle
+1 Schöne Sichtweise. Sie werden an diesem Blog-Beitrag interessiert sein, denke ich: database-programmer.blogspot.com/2010/12/… .
Lukas Eder
5

Die einzige Frage, die Sie stellen und die eine eindeutige Antwort hat, lautet "Ist SQL-Code oder Metadaten?". Es ist definitiv Code und sollte daher in einer Art Quellcode-Kontrolle aufbewahrt werden und über ein System verfügen, mit dem Sie problemlos auf die neueste Version aktualisieren und wann zurücksetzen können nichts schief geht.

Ich habe drei Möglichkeiten gesehen, SQL in einer Anwendung auszuführen, und jede hat ihre Vor- und Nachteile. Es gibt keinen besten Weg, aber das Beste ist, einfach einen auszuwählen, der gut zu Ihrer Anwendung passt, und dabei zu bleiben.

  • ORM - Dies reduziert die Menge an SQL, die Sie schreiben müssen, und verarbeitet viele Details für Sie. Sie müssen benutzerdefiniertes SQL ausführen. Stellen Sie sicher, dass Sie einen ORM haben, der dies ordnungsgemäß handhabt.
  • Datenzugriffsobjekte - Behalten Sie die SQL in den Objekten bei, die auf die Daten zugreifen. Dadurch wird Ihre Datenbank gekapselt und der Rest Ihrer Anwendung muss nicht über die zugrunde liegende DB-Struktur Bescheid wissen, sondern nur über die Schnittstelle zu diesen Objekten.
  • Gespeicherte Prozeduren - Dadurch bleibt Ihr gesamtes SQL in Ihrer Datenbank und Ihre DBAs können leicht erkennen, was gerade passiert. Alles, was Sie tun müssen, ist, dass Ihr Code die gespeicherten Prozesse aufruft
Kenny Drobnack
quelle
4

Wir verwenden zufällig den iBatis SQL-Mapper, der näher am Metall liegt als ORMs wie Hibernate. In iBatis fügen Sie die SQL-Anweisungen in Ressourcendateien (XML) ein, die sich im Klassenpfad befinden müssen.

Ihre Liste der Ansätze scheint ziemlich umfassend zu sein, wenn Sie die ORM-Option von @ ocdecio hinzufügen. Ich würde sagen, dass die Verwendung eines ORM und eines SQL-Mappers und von Ressourcendateien die beiden besten Ansätze sind. Ich würde mich von SQLJ fernhalten, das nicht viel Akzeptanz gefunden hat und Sie zu eng mit Java verbindet. Halten Sie sich auch von gespeicherten Prozeduren fern, da diese Sie an einen bestimmten Datenbankanbieter binden (Standards für gespeicherte Prozeduren sind fast nicht vorhanden).

Jim Ferrans
quelle
4

Wie die meisten von uns habe ich die ganze Gammut gesehen, aber wir müssen SQL als eine erstklassige Sprache betrachten. Ich habe sogar SQL in der Datenbank gespeichert gesehen, das heruntergezogen und dann wieder ausgeführt wird.

Die erfolgreichsten Systeme, die ich gesehen habe, verwenden gespeicherte Prozeduren, Funktionen und Ansichten.

Gespeicherte Prozesse halten den SQL-Text in der Datenbank zurück und ermöglichen eine relativ sofortige Änderung durch die DEPLOYING- und CUSTOMIZING-Prozesse (für deren Unterstützung viel geeignetes Design erforderlich ist).

Alle Projektionen sollten aus den gleichen Gründen über Ansichten und einfache Auswahlen erfolgen. Die gesamte Projektionslogik sollte in der Ansicht enthalten sein.

Jé Queue
quelle
+1 für die Erwähnung von Ansichten. Dies spiegelt sich noch nicht in der Zusammenfassung der Frage wider
Lukas Eder
2

Ich schlage vor, DAOs mit einem Factory-Layout zu verwenden. Die Beispielobjekte, die Sie benötigen, wären also:

public class CoolBusinessObject
public class DAOFactory.java
public implementation CoolBusinessOjectDAO
public class CoolBusinessOjectDAOOracleImpl implements CoolBusinessOjectDAO

Dieser Stil überlagert die Dateninteraktion, sodass Sie nur eine Codeebene ändern müssen, wenn Sie die Datenbank wechseln oder zu ORM-Technologien wechseln.

Jay
quelle
2

Es gibt keinen wesentlichen Unterschied zwischen diesen drei:

  1. In Geschäftsobjekten fest codiert
  2. Eingebettet in SQLJ Klauseln
  3. Kapselung in separate Klassen, z. B. Datenzugriffsobjekte

Ich gehe davon aus, dass Sie SQL-Code in einer Zeichenfolge direkt in Ihren Java-Code einbetten. Während 1 und 3 wahrscheinlich JDBC direkt verwenden werden (oder ein Tool wie Apache DbUtils ), fügt 2 dem Stapel eine Präprozessortechnologie hinzu, die den relevanten JDBC-Code vor der Kompilierung generiert.

Wenn diese Lösungen das Einbetten von SQL beinhalten, können Sie im Wesentlichen auch eine der folgenden Technologien verwenden:

  • JPA Criteria API , Modellierung von JPQL als interne domänenspezifische Sprache in Java
  • jOOQ , Modellierung von SQL als interne domänenspezifische Sprache in Java

Möglicherweise gibt es auch andere Tools, mit denen Sie SQL typsicherer in Java einbetten können als durch SQLJ oder durch tatsächliche Verkettung von Zeichenfolgen.

Lukas Eder
quelle
1

Aus meiner Erfahrung heraus ist die harte Codierung von SQL-Anweisungen in den DAO-Objekten weit verbreitet. Ich denke jedoch, dass dies die am wenigsten bevorzugte Methode sein sollte. Die beste Vorgehensweise sollte darin bestehen, die SQL-Anweisungen in einer Eigenschaftendatei zu speichern. Rufen Sie die Anweisungen im DAO-Objekt über eine Schnittstelle zu Eigenschaftendateien ab, z . B. java.util.Properties . Die SQL-Anweisungen können mit '?' Durchsetzt werden, um Parameter über eine vorbereitete Anweisung zu übergeben Ansatz für .

Ein solcher Ansatz hilft dabei, die SQL-Logik von der Geschäftslogik der Anwendung zu entkoppeln. Dadurch wird ein zentrales Repository für alle SQL-Anweisungen verfügbar, wodurch die Änderung vereinfacht wird und die Suche nach Datenbankanweisungen innerhalb der Anwendungslogik entfällt. Die Verständlichkeit wird ebenfalls verbessert.

Die Maschine
quelle
Einige Leute könnten einwenden, dass dies das Risiko einer SQL-Injection mit sich bringt. Was ist deine Meinung dazu?
Adrian
2
Wenn Sie den SQL-Code ohnehin außerhalb der Anwendung speichern, welchen Vorteil hat das Speichern als Zeichenfolgen irgendwo gegenüber dem Speichern in der Datenbankebene (als gespeicherte Prozeduren)? Gespeicherte Prozeduren können den Optimierer Ihrer Datenbank effektiver nutzen, sodass sie vorbereitete Anweisungen fast immer übertreffen.
Daniel Pryden
1
Hallo Daniel, ich meinte nicht, du schreibst keine SQL-Prozesse, ich meinte nur, du nennst die gespeicherten Prozesse so, wie ich es erwähnt habe. Es hilft Ihnen, eine bessere Kontrolle über die Übergabe von Parametern an den gespeicherten Prozess zu haben.
Die Maschine
1

Meine landen in Ressourcenbündeln. Ich weiß, dass es nicht normal ist, aber es ist für mich und jeden "außer mir" am einfachsten zu pflegen. Es ist einfach und logisch.

Ich bin eigentlich gespannt, ob jemand meinen Ansatz auch nutzt.

Brett Ryan
quelle
Neugierig, warum Sie das SQL nicht in der Datenbank behalten?
Jé Queue
@Xepoch - Wie meinst du das? Die Anweisungen befinden sich in Ressourcenpaketen (Eigenschaftendateien), die sich im selben Paket wie die Entitäten befinden. Daher bezieht sich customer.properties auf Customer.class. Daten werden in der DB gespeichert.
Brett Ryan
1

Als Rexem schrieb, sind SQL-Anweisungen Code - sie sollten wie Code behandelt werden, nicht externalisiert (außer Sie haben gute Gründe), sondern mit Code platziert werden, der SQL-Daten von / zu diesen Anweisungen verarbeitet. Die heutigen Framework-ORMs / iBatis bieten viele Vereinfachungen für die tägliche JDBC-Entwicklung.

Einige Antworten auf Ihre Frage finden Sie in dieser Frage :) Das Problem, wie Ihre SQL-Anweisungen gespeichert werden, hängt vom König Ihrer Anwendung ab. Was sind deine Bedürfnisse? Hohe Sicherheit, einfaches Schreiben von Code oder Wartung, plattformübergreifende oder Lieferantenbindung? Die nächste Frage, die Sie benötigen, ist ein reines SQL- oder ORM-Framework.

* Hardcoded in business objects
* Encapsulate in separate classes e.g. Data Access Objects

Einfachste Lösung (P), schwer zu warten (C)

* Embedded in SQLJ clauses

Beter Syntaxprüfung (P), Mangel an dynamischen Abfragen (C), geringere Leistung als JDBC (C), nicht so beliebt (C)

* Metadata driven (decouple the object schema from the data schema - describe the mappings between them in metadata)

Es muss ein konkreter Fall sein, dass Sie dies tun sollten (C) oder wenn Sie ORM (P) meinen;)

* External files (e.g. Properties or Resource files)

Leicht zu pflegen (P), aber schwerer auf Fehler zu überprüfen (C)

* Stored Procedures

Hohe Sicherheit (P), Code, der schwer zu lösen ist, um Probleme mit der Lieferantenbindung zu lösen (C)

cetnar
quelle