Struktur eines Datenbankinterface?

Status
Nicht offen für weitere Antworten.

netz-rack.c

Mitglied
Hallo,

ich habe mal gelernt, ich solle meinen Code überdenken, wenn ich merke das ich den selben Code mehrmals schreibe.

Daher kommen mir bei meinem aktuellem Design doch so einige Zweifel:

Zum Problem: Ich soll eine Oberfläche für eine Datenbank schreiben, die den Werkbestand uns sie zugehörigen Fotos in unserem Museum erfasst. Da ich hier poste arbeite ich ja ganz offensichtlich mit Java und stelle die Verbindung zur PostgreSQL-Datenbank per JDBC her.

Ich habe also begonnen, die einzelenen Ansichten mit Logik zu füllen, dabei merke ich, dass ich immer wieder die Datenbankverbindung initialisiere und abfragen ausführe. Dazu ist aber fast immer der selbe Code notwendig (zumindest bis zu dem Punkt, an dem ich die Abfrageergebnisse auf Objekte ummünze)
Kann man diesen Code nicht irgendwie in eine Klasse auslagern, die die eine Verbindung hält, und darüber immer wieder neue Abfragen auwsführt, vielleicht sogar mit einem FIFO-Zwischenspeicher, der einen Forschrittsbalken oder irgendeine andere Rückmeldung an den Benutzer gibt?

Anscheinend habe ich hier vom Programmdesign bzw. von der Objektorien her ein Denkproblem.

MfG
Carsten


Ach, bevor ich's vergesse und wer meckert, hier noch kurz ein Beispiel für den Teil der sich wiederholt:
(Es sind zwar meißtens SELECT-Abfragen und keine Updates, ich hatte aber gerade diesen Teil (Stichwortzuweisung) geöffnet)

Code:
try {
			Class.forName(DB_DRV);
		} catch (ClassNotFoundException e) {
			JOptionPane.showMessageDialog(this.getRootPane(),
				    "Konnte Datenbanktreiber nicht finden!!",
				    "Datenbank-Fehler",
				    JOptionPane.ERROR_MESSAGE);
			e.printStackTrace();
			return;
		}
		
		try {
			Connection c = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
			
			Statement s = c.createStatement();
			
			try {
				s.executeUpdate("INSERT INTO \"BDB-1.0\".stichwort(wort) VALUES ('"+stwName+"')");
			} catch (org.postgresql.util.PSQLException e) {
				JOptionPane.showMessageDialog(this.getRootPane(),
					    e.getLocalizedMessage(),
					    "Datenbank-Fehler",
					    JOptionPane.ERROR_MESSAGE);
				e.printStackTrace();
			}
		
			s.executeUpdate("INSERT INTO " +
					"\"BDB-1.0\".verschlagwortung(werk_id, stichw_id) " +
						"SELECT " +
							"werk_id, stichw_id " +
						"FROM " +
							"\"BDB-1.0\".werk, " +
							"\"BDB-1.0\".stichwort " +
						"WHERE " +
							"werk_id="+ werk_id +
							" AND " +
							"wort='" + stwName + "'");
		
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(this.getRootPane(),
				    e.getLocalizedMessage(),
				    "Datenbank-Fehler",
				    JOptionPane.ERROR_MESSAGE);
			e.printStackTrace();
			return;
		}
 
S

SlaterB

Gast
soviel Code hast du ja gar nicht mal,

da sind zum einen die Fehlermeldungen, was wenig mit JDBC zu tun hat, eher mit Swing,
die könntest du kürzen zu einer Operation a la
showDBError(e);

der Rest ist gar nicht so übel, eine Anfrage als SQL geht mit geringen Aufwand kaum kürzer,
du könntest das alles in eine Logikklasse auslagern:

try {
logicObject.doXyUpdate(Parameter);
} catch (ClassNotFoundException e) {
} catch (SQLException e) {
...

hast dann natürlich den Aufwand mit den Parametern..


--------

den Treiber solltest du eh nur einmal beim Programmstart laden,
dann kann es danach ClassNotFoundException nicht mehr geben

--------

auf SQLFehler anders zu reagieren als in der GUI SQLException abzufangen wäre auch zu empfehlen,
ist aber wieder etwas aufwendiger
(Statusfeld oder eigene Exception)
 

netz-rack.c

Mitglied
Naja, das Hauptproblem ist ja eher der massive Codeblock, wenn ich die Daten aus der Datenbank ins GUI schreibe, also in dem Beispiel hinter dem UPDATE.

Mein gefühl sagt mir ich sollte diese Logik von dem GUI trennen. in einem Fall habe ich das auch schon mit einer Extraklasse gemacht, die den Swingworker benutzt um das ganze auch aus dem AWT-Thread rauszuhalten.
Was imho gerade bei der bearbeitung von BLOBs ganz gut ist, da die JAI-Operationen immer so lange brauchen.

Ich hätte nur gern eine algemeine Lösung, bei der ich solche Anfragen einreihen könnte.

Demnächst bekomme ich ganze Listen von Bildern mit Informationen die alle verarbeitet werden wollen. In dem Fall würde das erste Internal Frame ja bei hoher Belastung (Binary-Stram verarbeiten) ja die ganze Anwendung lam legen. Ich würde also gerne das Ganze JDBC/Netzwer/JAI-Zeug aus dem AWT-Thread rausbekommen, wenn es geht aber so, das ich trozdem noch Rückmeldungen an den User geben kann. (z.b. über setProgress() im SwingWorker)

Ich bin in dem Zusammenhang gerade über Hibernate gestolpert, lohnt es sich, dass ich es mir mal ansehe? Oder ist es zu komplex um es in (relativ) kurzer Zeit benutzen zu können? (bin eher Java-Autodidakt troz einm halben Jahr Unterricht damals in der Schule :### )


MfG
Carsten
 
G

Guest

Gast
Wie wäre es mit sowas dieser Art. Schreibe eine abstrakte Klasse, die
solche Verwendung ermöglicht.
Die eigentlichen Aufrufe der Methoden kannst du dann in einen SwingWorker
vepacken und schon hast du eine saubere Trennung zwischen Persistenz- und
GUI-Logik.
Oder vergiss das ganze und verwende einen vernünftigen OR-Mapper. ;)
Code:
public final class BookDB extends AbstractDB<Book>
{
   /**
   * Privater Konstruktor.
   * Nicht instanzierbare Util-Klasse mit lauter static-Methoden.
   */
   private BookDB() {}

   /**
   * Callback von AbstractDB. Wird für jede Zeile des ResultSets aufgerufen.
   * ...
   */
   protected static Book getValue(ResultSet rs) throws SQLException;
   {
      Book result = new Book();

      // DBUtil ist eine Hilfsklasse, die das Lesen von Parametern vereinfacht/verkürzt
      //
      // z.B. Lesen von Int aus ResutSet
      //
      // public static Integer getInteger(ResultSet rs, String fieldName) throws SQLException
      // {
      //    int intValue = rs.getInt(fieldName);
      //    return !rs.wasNull()? Integer.valueOf(intValue) : null;
      // }

      result.setISBN(DBUtil.getString(rs, "isbn"));
      result.setAuthor(DBUtil.getString(rs, "author"));
      result.setTitle(DBUtil.getString(rs, "title"));
      return result;
   }

   public static List<Book> getBooksByAuthor(String author) throws DAOException
   {
      try
      {
         // getValueList ist eine generische Methode in AbstractDB und bedient sich
         // der überschriebenen Methode getValue(ResultSet rs), um die einzelnen
         // Zeilen in Book-Instanzen zu konvertieren
         // Signatur: protected static List<T> getValueList(String sqlStatement, Object ... args) throws SQLException
         return getValueList(
            "SELECT isbn, author, title FROM Book WHERE author = ?",
            author
         );
      }
      catch(SQLException e)
      {
         Logger.error(e);
         // hier evtl. noch eine Fehlermeldung setzen, damit der User nicht mit SQL-Meldungen
         // schockiert wird.
         // z.B. new DAOException(String.format("Fehler beim Lesen von Büchern anhand des Authornamens (%1$s).", author), e);
         throw new DAOException(e);
      }
   }

   public static Book getBookByISBN(String isbn) throws DAOException
   {
      try
      {
         // getValue ist eine generische Methode in AbstractDB und bedient sich
         // der überschriebenen Methode getValue(ResultSet rs), um das Ergebnis
         // der Abfrage in eine Book-Instanzen zu konvertieren.
         // Signatur: protected static T getValue(String sqlStatement, Object ... args) throws SQLException
         return getValue(
            "SELECT isbn, author, title FROM Book WHERE isbn = ?",
            isbn
         );
      }
      catch(SQLException e)
      {
         Logger.error(e);
         throw new DAOException(e);
      }
   }

}
 

netz-rack.c

Mitglied
Und ein solcher O/R-Mapper lagert ide Arbeit dan auch vernünftig in externe Threads aus?

Wenn Hibernate jetzt noch die möglichkeiten für Fortschrittsanzeige oder ähnliches bietet und nicht zu komplex ist, so währe es die Ideale Lösung!!?
 

KSG9|sebastian

Top Contributor
Hibernate? Ne Fortschrittsanzeige?
Weiß du was Hibernate ist? Hibernate ist für die Persistenz und das Mapping Datenbank <-> Java Objekte zuständig. Nicht mehr, nicht weniger. Es tut im Endeffekt nichts anderes wie deine Methode welche einen SQL-Query abfeuert und aus dem Resultat ein Objekt baut. Nur das du eben nichtsmehr mit JDBC zu tun hast und Hibernate 100000x komplexer ist als meine Beschreibung :)
Auch mit Hibernate wird dir nichts anderes übrig bleiben als die Performancelastige Arbeit auszulagern
 

netz-rack.c

Mitglied
hmn, ... OK
(Bei der Fortschrittsanzeige hast du mich vmtl. falsch verstanden, mir ging es darum, ob Hibernate Auskunft über den Status/Fortschritt des mapping-Vorgangs gibt)

Wenn ich jetzt also das MVC-Designmuster als Idee benutze, so ist Hibernate bzw die von ihm hergestellten Objekte nur das Modell??

Währe es demnach also der leistungsfähigste Weg, wenn der Controler Hibernate (wenn es geht in einem eigenen Thread) startet und die Objekte dann in das GUI (View) schreibt?
 
G

Guest

Gast
Hibernate ist nicht das Model. Das Model bedient sich Hibernate, um an Daten ran
zu kommen.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
OnDemand Struktur für Parent / Child Produkt Datenbankprogrammierung 5
DStrohma Kann sich jemand mal diese DB-Struktur ansehen? Datenbankprogrammierung 2
G Datenbasis SQL, Struktur XML Datenbankprogrammierung 5
L Struktur einer vorhandenen Datenbanktabelle ändern Datenbankprogrammierung 8
M Struktur Datenbankanwendung Datenbankprogrammierung 10
Robert Zenz Aufteilen von Up/Downvotes eines Benutzers in drei Gruppen. Datenbankprogrammierung 0
H Oracle Resize eines Images in Java und Rückgabe des Image als BLOB an die Oracle Datebank Datenbankprogrammierung 14
damike84 Hibernate: persistieren eines Graphen Datenbankprogrammierung 2
G Laufzeit eines Algorithmus mittels Big Theta bestimmen Datenbankprogrammierung 5
G ID zuweisung eines TerminKalenders (mehrere Kalender) Datenbankprogrammierung 8
D Hibernate: Zustand eines Objekts erkennen? Datenbankprogrammierung 0
S HSQLDB Verbieten eines update auf eine bestimmte reihe Datenbankprogrammierung 4
J Datenbankeintag eines Warenkorbes funktioniert nicht Datenbankprogrammierung 4
H MySQL Werte eines Datensatzes in einen anderen kopieren Datenbankprogrammierung 2
M [Hibernate]Abgleich eines lokalen Objekts mit dem Zustand aus der Datenbank. Datenbankprogrammierung 3
N Problem bei Erstellung eines Index Datenbankprogrammierung 12
G PostgreSQL Postgre: Passwort eines Benutzers ändern Datenbankprogrammierung 3
D Anzeige wärend des Ausführens eines Statements Datenbankprogrammierung 13
N executeUpdate "innerhalb" eines Resultsets Datenbankprogrammierung 14
S Select eines bestimmten Datensatzes Datenbankprogrammierung 4
J Kopieren eines Datensatzes Datenbankprogrammierung 4
R Effiziente Java-Methode zum finden eines freien PK Datenbankprogrammierung 7
M Zugriff auf eine Access-Datenbank innerhalb eines jar-Files Datenbankprogrammierung 7
brainray Bei MySQL alle Datenbanken eines Servers abfragen Datenbankprogrammierung 3
1 User die Rechte eines Datenbankerstellers zuweisen? Datenbankprogrammierung 3
X SQL Abfrage für Ähnlichkeit eines Strings Datenbankprogrammierung 2
B SQL Abfrage. Nur den ersten eines Blocks Datenbankprogrammierung 2
M Passwort eines Technischen Users hinterlegen Datenbankprogrammierung 6
A JPA: Zweite Instanz eines Entitätsobjekts Datenbankprogrammierung 3
M Konvertierung eines Ojects to String Datenbankprogrammierung 3
T Datenbanknamen eines Datenbankservers auslesen Datenbankprogrammierung 9
J Größe eines ResultSets Datenbankprogrammierung 12
G Problem beim Schreiben eines Dateipfads in MySQL-DB Datenbankprogrammierung 9
G Löschen eines Eintrages verbunden mit JList Datenbankprogrammierung 5
F Filtern innerhalb eines Resultset Datenbankprogrammierung 12
W Anzahl der Spalten eines ResultSets bestimmen Datenbankprogrammierung 5
F die DN eines LDAP verzeichnisses abfragen Datenbankprogrammierung 2
B Laden eines JDBC Treiber. Datenbankprogrammierung 7
P Wirkliche Zeilenanzahl eines ResultSets ermitteln Datenbankprogrammierung 22
K frage zum ausführen eines INSERT statements Datenbankprogrammierung 16
K errechnen eines mittelwertes vom jdbc rSet Datenbankprogrammierung 4
M Abfrage trennt Ergbnis eines Atrributes nach den Leerzeichen Datenbankprogrammierung 4
F Abfrage eines DB Feldes aus einer mySQL Datenbank Datenbankprogrammierung 2
K Datenbank eines Forums nutzen Datenbankprogrammierung 11
J Alle Spalten und Zeilen eines ResultSets ausgeben ? Datenbankprogrammierung 2
B Zeilenzahl eines ResultSet ermitteln Datenbankprogrammierung 5

Ähnliche Java Themen

Neue Themen


Oben