Java Datenbank in Java Anwendung integrieren

Fonce

Captain
Registriert
Feb. 2006
Beiträge
3.377
Hi,
ich möchte eine Java Anwendung mit ein integrierten Datenbank schreiben. Die Datenbank soll also lokal mit der Anwendung ausgeliefert werden.
Ich habe mir schon HSQLDB angeschaut, finde es allerdings nicht so schön das diese zwei Dateien benötigt welche noch dazu in Klartext geschrieben werden.
Gibt es hier eine andere Möglichkeit? Gut wäre auch wenn JPA diese Datenbank unterstützt.

mfg,
Fonce
 
Hi,

was ist denn mit üblichen Verdächtigen wie MySQL oder SQLite? Bei Ersterem müsste auf dem PC/Server ein MySQL Server laufen, SQLite hingegen speichert die DB in eine Datei.
Das ganze dann mit JDBC an Java anbinden sollte eigentlich recht reibungslos funktionieren.
 
Zuletzt bearbeitet:
Ja die Daten sollen persistent vorgehalten werden. Das Speichern als XMList hier auch eine sehr unschöne Lösung, da über die Jahre eine ziemliche Datenmenge anfallen dürfte.
In wieweit eignet sich SQLite den zum Speichern von Geldbeträgen?
 
genauso wie alles andere auch, sind eh am Ende alles Binärdaten. Geldbeträge sollten nach Möglichkeit sowieso immer als Integer berechnet werden. Float-Operationen und Geld... da steht man schnell mal bei einem Kunden mit 4Mrd in der Kreide.
 
Kannst die Beträge normal als Float bzw. Real speichern: http://www.sqlite.org/datatype3.html

@Daaron: seit wann sollte man Float als Integer speichern? Ich glaube, wenn ich statt Float, Integer verwende, werden bei uns 30 Mio Kunden ganz schnell ungemütlich ;-)
 
Man speichert als Integer (oder ähnliches), weil Float nicht genau ist (Man kann nicht jede Komma-Zahl exakt darstellen und deshalb wird ein Wert genommen der möglichst nah ran kommt).
Dann hast du irgendwo irgendwann mal hier und da ne komische (und falsche) Rundung drin und schon ist der Betrag fehlerhaft. Macht für ne Taschengeld-App oder so keinen Unterschied, aber bei einen paar Millionen Transaktionen am Tag rechnet sich sowas sehr schnell und wer verschenkt schon gerne Geld.
 
Geldbeträge haben üblicherweise 2 Nachkommastellen. Ist dir nie aufgefallen, dass eine Kassiererin im Supermarkt direkt eine dreistellige Zahl eingibt, wenn du etwas für 3,95 kaufst?

Wenn du also statt 100,00 direkt 10.000 speicherst und am ENDE dann von Integer in Double/Float umwandelst (mit ner Division durch 100), hast du keine Probleme. Wenn du hingegen permanent mit Float arbeitest kann das zu extremen Fehlern führen. Sinngemäß könnte folgendes passieren:
3*5 - 2*7,5 = 0,00001

Floats sind grundsätzlich NICHT präzise. Es gibt sogar ganze Zahlen, die mit Float nicht dargestellt werden können. Die Präzision hängt von der Länge der Mantisse ab. Da selbige limitiert ist, ist auch die Präzision limitiert.

Ein kleines Beispiel für das was passieren kann, wenn man mit Float rechnet:
http://haupz.blogspot.de/2009/01/ich-bin-reich.html
 
Warum man Geldbeträge nicht als Float speichert? Ist das jetzt dein erst? Wegen der Genauigkeit von IEEE754(Spezifikation für 8Byte Gleitpunkt) vieleicht? :rolleyes:

Ich werde wohl auf SQLite setzen hab mich da mal kurz eingelesen und SQLite hat den Datentyp NUMERIC welcher Decimal entspricht.
 
@Fonce: Ja, eben wegen diesem Präzisionsproblem solltest du kein Float verwenden.

http://javathreads.de/2009/03/niemals-mit-den-datentypen-float-oder-double-geldbetraege-berechnen/

Code:
System.out.println("1.0 - 1.0 = " + new Double(1.0 - 1.0));
System.out.println("1.0 - 0.9 = " + new Double(1.0 - 0.9));
System.out.println("1.0 - 0.8 = " + new Double(1.0 - 0.8));
System.out.println("1.0 - 0.7 = " + new Double(1.0 - 0.7));
System.out.println("1.0 - 0.6 = " + new Double(1.0 - 0.6));
System.out.println("1.0 - 0.5 = " + new Double(1.0 - 0.5));
// Ausgabe:
// 1.0 - 1.0 = 0.0
// 1.0 - 0.9 = 0.09999999999999998
// 1.0 - 0.8 = 0.19999999999999996
// 1.0 - 0.7 = 0.30000000000000004
// 1.0 - 0.6 = 0.4
// 1.0 - 0.5 = 0.5
 
Schon klar, NUMERIC bzw. DECIMAL ist ist ja auch ein Integer Wert bei dem zusätzlich die Gesamtstellen und Nachkommastellen angegeben werden. Java hat hier z.B auch Datentypen für, z.B. BigDecimal. ;)
 
sasdensas schrieb:
Ich glaube, wenn ich statt Float, Integer verwende, werden bei uns 30 Mio Kunden ganz schnell ungemütlich ;-)
Heftig. Ich glaube ich sollte bei Onlinegeschäften mal mehr aufpassen. Ich dachte, dieses Detail wird in jedem besseren Grundlagenbuch erwähnt. Bzw. klar, Integer selbst nicht, aber Float geht halt gar nicht.
 
Fonce schrieb:
Schon klar, NUMERIC bzw. DECIMAL ist ist ja auch ein Integer Wert bei dem zusätzlich die Gesamtstellen und Nachkommastellen angegeben werden. Java hat hier z.B auch Datentypen für, z.B. BigDecimal. ;)
Nicht jede Sprache hat solche Datentypen, aber jede hat den Float-Kasper. Im Zweifel baut man sich eine Lösung über Integer.
 
Die IEEE-Geschichte bei Float ist mir natürlich nicht fremd. Ich bin hauptsächlich mit SAS unterwegs, wo es auch nur die beiden Datentypen Nummerisch und Alphanumerisch gibt. Gleitkommazahlen werden intern als Integer abgelegt (dank Cobol) und visuell als Gleitkommazahl.
Beträge werden i.d.R. nach dem Muster xxxxx,xx gespeichert. Ein Präzisionsverlust entsteht, wenn eine Zahl mit einer Nachkommastellen > 2 gepeichert wird. Die DB Engine sollte in der Lage sein genauere Werte zu Runden. Das Problem betrifft letztendlich Aggregation im analytischen Bereich. Die Entwickler sollten in der Lage sein, dieses Problem mit eigenen Algorithmen zu behandeln. Geht es nur um die Speicherung von Beträgen, dann ist Float, bzw. Double oder Bigfloat/Bigdouble durchaus Sinnvoll. Aggregationen sollten wohl überlegt werden. Integer wird aber in dem Fall keine Lösung bieten.
 
Zuletzt bearbeitet:
Da es um Geldbeträge geht, sind double und float eben keine Option...
 
Zumal es nicht NÖTIG ist, Float zu nutzen. Sogar SQLite (was nun wirklich ein minimalistisches Datenbank-System ist) kennt NUMERIC und DECIMAL, die für präzise Speicherung und Berechnung von Werten verwendet werden können.
 
http://www.db4o.com/ , gut als embedded db und da sparst du dir den OR Mapper und kannst POJOs einfach in die DB werfen, ohne dass du sie anpassen müsstest. SQL würde ich da nicht mehr benutzen.

Person John = new Person("John", 45);
db.store(John);

fertig, einfach so.
 
Zuletzt bearbeitet:
Zurück
Oben