Java H2 Datenkbank - speichern einer Klasse in zwei Tabellen

Tr3x

Lieutenant
Registriert
Feb. 2007
Beiträge
650
Hallo,

ich bin hier etwas am werkeln. Und zwar habe ich eine Klasse Kontakt. Diese Hat bis auf Vor und Nachnamen auch eine Adresse. Diese würde ich gern in die Datenbank speichern. Ich verwende hierzu H2.
Nun jetzt könnte ich das Object einfach der Datenbank geben und diese speichert alle Attribute in eine Tabelle. Jetzt finde ich das die Adresse in eine andere Tabelle gespeichert werden könnte. Schon wegen der redundanzt der Postleitzahlen.

Ich hab leider keine Idee wie ich das anstelle. Habt Ihr da ein paar Tipps oder eine Anleitung?
 
Du musst entscheiden ob du direkt mit JDBC drauf zugreifen willst, oder ob du den JPA-Weg gehst. Der Einfachheit halber wirst du vermutlich JDBC benutzen. Da arbeitest du dann mit gewöhnlichem SQL und kannst das Persistieren selbst steuern, d.h. auch, in welche Tabelle die Adressdaten fließen.
 
Hey. Dachte ich es mir fast das ich uber den jpa weg gehen musste. Da stellt sich mir nur die frage wie ich das mit der h2 datenbank mach. Gibt es da irgendwo was zum nachlesen?

Und wie wurde ich den ersten weg verwenden. Ich hab jetzt sagen wir eine klasse mit name und adresse als attribut die jewiels in eine tabelle gespei hert werden mussten. Ich musste diese dann in zwei sql statemants in die db speichern, oder? Wie wurde ich hier dann eine beziehung erstellen? Wenn es hier au ein tutorial geben wurde war das naturlich au super
 
Für den JDBC-Weg:
http://www.h2database.com/html/tutorial.html#connecting_using_jdbc
und dann entsprechend
http://docs.oracle.com/javase/tutorial/jdbc/basics/index.html

Und dann hätte die Klasse z.B. eine Methode persist(), die, wie du schon gesagt hast, 2 PreparedStatements ausführt. Die Verbindung in der DB stellst du ganz gewöhnlich per foreign key her. D.h. in der Tabelle Kontakt gibt es neben id, name und vorname auch addresse_fk (o.ä.), wo einfach nur der primary key der zugehörigen Adresse in der Adress-Tabelle steht.

Beim Laden eines Kontakts musst du dann entsprechend sowas machen wie
Code:
select * from address a where a.id = <address_fk des zu ladenden Kontakts>
und dann wrapst du das in ein Address-Objekt auf Java-Seite, damit du vernünftig damit arbeiten kannst.

Es ist eben viel mehr händische Arbeit, als bei JPA. Allerdings sparst du dir lib dependencies und hast weniger initialen Konfigurationsaufwand. Daher lohnt JPA eher, wenn du die Konfiguration dafür schon aus dem Ärmel schütteln kannst oder wenn du mit wesentlich mehr als 2 Entitäten arbeitest.

Für den JPA-Weg würde ich schon aus Gewohnheit auch Spring benutzen. Auch um nicht händisch DAOs schreiben zu müssen. Kannst dich ja mal hier umsehen.
 
Hey,

klasse. Ich denke wenn ich jetzt schon auf den JDBC Tripp bin werde ich da mal weiter ansetzen. Das Speichern wäre mir jetzt schon klarer. Hoff ich jetzt zumidnest.

Wenn ich jetzt meine Klasse Kontakt habe. Mit den Namen und der Adresse habe. Dann pflück ich das einfach in die entsprechende SQL Statements damit diese in zwei TAbellen gespeichert werden. Jetzt würde es mich zum Verständnis interessieren, wie es mit dem umgekehrten weg aussieht, also wenn ich mir die Daten hole.

Da müsste ich vermutlich einen Inner bzw Left Join machen, richtig?
 
Wenn du alles mit einem Query holen willst, dann ja. Wenn nicht jeder eine Adresse hat left, sonst inner join. Alternativ kannst du ein Query für die Kontaktdaten und eine separate Abfrage für die Adresse haben. Das hatte ich im letzten Beitrag schon so beschrieben.

Beim Laden eines Kontakts, wird dann entweder direkt im Konstruktor oder aber lazy erst beim ersten Abruf die zugehörige Adresse geladen. Ist natürlich auch ganz nett, von deiner Million Kontakte nicht direkt alle Adressen zu laden, sondern erst, wenn sie wirklich gebraucht werden. Bei JPA können solche Sachen auch lazy geladen werden und bei Hibernate ist das z.B. Standard.
 
alles klar. dann werde ich das mal alles ausprobieren. vielen dank schon mal
 
Tr3x schrieb:
[... ]Schon wegen der redundanzt der Postleitzahlen.

WIE BITTE?

Du willst Postleitzahlen normalisieren? Das ist (entschuldige bitte) extremer Blödsinn!

Eine PLZ ist eine Zahl. Also wird sie in der DB als Integer gespeichert. Wenn du die jetzt in eine andere Tabelle auslagerst, wie referenzierst du dann deine PLZ wieder? Also welches Format haben deine Primary Keys? Im (speicherplatzmäßig betrachtet) kleinsten Fall: Integer! Oder du nimmst die PLZ selbst als Primary Key, aber dann ist das ganze noch sinnloser ;)
Den Ortsnamen zusätzlich zur PLZ zu speichern ist auch nur bedingt möglich, da man dann keinen Ortsteil mehr mit angeben kann - was ja gelegentlich erwünscht ist.

D.h. du sparst am Ende keinen Speicher, sondern vergeudest welchen, weil für jede PLZ jetzt noch zusätzlich ein Primary Key erzeugt werden muss.
Dazu kommen noch die unnötigen JOINs bei den Abfragen. Und unnötige Constraint Checks beim INSERT.
Deine Querys werden auch nicht schneller, weil du so oder so für die Suche einen Index auf die Spalte mit der PLZ legen solltest.

BTT: JDBC oder JPA?
JDBC würde ich nur nutzen, wenn ich eine fremde Datenbank an meine Applikation anbinden muss, die sich nicht so wirklich schön bei JPA abbilden lässt, oder wenn die Querys zu komplex werden und viele Aggregatsfunktionen enthalten.
In allen anderen Fällen: JPA! Deine Tabellen können automatisch erzeugt werden, Constraints werden automatisch gesetzt, du musst dich nicht mit 'nem RowMapper rumschlagen, etc. pp..
Das ganze dann in Kombination mit QueryDSL und/oder JPA Criteria Querys und/oder Spring Data JPA. Dann macht das Arbeiten mit Java und RDBMS auch gleich wieder Spaß :)
 
benneque schrieb:
Eine PLZ ist eine Zahl. Also wird sie in der DB als Integer gespeichert.
Eine PLZ als Zahl zu speichern ist ebenso Blödsinn. Es sei denn, du beschränkst dich ausschließlich auf deutsche PLZen.
Einige unserer Nachbarländer setzen da gerne Buchstaben rein. Außerdem musst dann bei der Ausgabe auf eine korrekte Formatieren achten, wenn die PLZ mit 0 beginnt. Diese darf dann aber wiederum nicht vor eine luxemburgische PLZ gesetzt werden, etc.
 
Sowas kannst du mir um halb 4 morgens nicht vorwerfen :D Es gab Tequila!

Halten wir fest, dass es bei Adress-Daten (PLZ, Str, Hausnummer, etc.) und anderen persönlichen Daten (Vorname, Nachname, etc.) keinen Sinn macht diese aus Redundanzgründen in eine andere Tabelle auszulagern.
 
Zurück
Oben