Du hast die String + sache ja nicht nur bei der einen Funktion sondern an mehreren Stellen.
Noch mal zum Thema immutable Keys... Die Keys sollen ja die DB-Abfragen beinhalten. Andere DB-Abfragen haben andere Resultate zur Folge. Ferner folgt daraus, dass veränderte DB-Abfragen nebst ihren Resultaten ohnehin neu in den Cache aufgenommen werden müssen. Das einzige, was sich an dem Schlüssel ändert wäre der Usecount bzw. der Zeitpunkt, an dem die Abfrage zum letzten mal stattfand. Diese Werte sind aber weder für "equals()" und "hashCode() noch für "compareTo()" relevant und können dort ignoriert werden. Den Rest der Schlüsselklasse kann man deswegen immutable gestalten, das ist definitiv um einiges performanter, weil das ständige Rehashing entfällt. "hashCode()" selbst könnte man dann z.B. mit 32-Bit RSA oder CRC32 per Objektserialisierung implementieren, der Hashcode wäre ja dann final.
BTW: Betrifft den oben genannten Begriff Usecount...
Als gute Idee hat sich bereits folgendes ergeben. Die Abfrage erhält bei ihrer ersten Verwendung einen Zeitstempel und einen Usecount von 1. bei jeder erneuten Verwendung inkrementiert man den Usecount. Mit einer Formel wie [c]currentTime - timeStamp <= useCount * minTimeToCache[/c] kann man so aufgrund der Häufigkeit der Verwendung entscheiden, wann die Abfrage aus dem Cache entfernt werden soll. Höhere UseCounts bedeuten längere Cache-Zeiten. Natürlich kann man die Formel auch so umstellen, dass man den Zeitstempel lediglich um minTimeToCache pro Verwendung erhöhen kann.
Also ich kann dir sagen warum die DB bei dir so lahmt: Dein DB Manager ist Müll. Du machst ja bei jedem Update/Insert/irgendwas ein System.out.println. Das bremst SO enorm, wenn du das bei deinem HashTable auch machen würdest, lägst du in der gleichen zZ
Aber es ist einfach nicht sinnvoll sich über Performance und Caching gedanken zu machen, wenn der Code des DB Controllers dermaßen ineffizient ist. Und ich muss dir hier ja nichts beweisen, du bist der mit dem Performaceproblem
Ich kann dir sagen was du falsch machst:
Nochdazu ist deine Konstruktion etwas unübersichtlich zu durchblicken. Normalerweise hat man z.B für ein Insert in eine Tabelle eine Funktion, in der steht der nicht veränderbare sql String fürs Prepared Statement z.B "INSERT INTO emp (vorname,nachname) VALUES(?,?)". Ohne zusammenbauen und ohne weiterreichen in irgendeine fastInsert Funktion.
- Du bastelst bei jeder Abfrage einen neuen String zusammen.
- Du schliesst deine Statements nicht.
- Du erledigst alles über eine einzelne Connection.
- Du machst mehrere System.out.printlns bei jeder Abfrage.
Naja wahrscheinlich Reduzierung von Objekterzeugungen oder nicht? Es macht schon einen Unterschied, ob ich für (1,2,3, "a") jeweils n- XXXKey's erzeuge, oder nur einmal, und das Teil dann poole/share.
1. Hast du Recht, aber aus irgendeinen Grund optimiert das JAVA weg ...
zumindes bei mir^^
Ist ja auch eine Quick und Dirty Klasse, sonst arbeite ich immer mit PreparedStatments ...
2. Mist, da hast du Recht xD
3. Willst du für jede Abfrage eine eigene Connection machen? Wie sollte man es denn machen?
Naja wahrscheinlich Reduzierung von Objekterzeugungen oder nicht? Es macht schon einen Unterschied, ob ich für (1,2,3, "a") jeweils n- XXXKey's erzeuge, oder nur einmal, und das Teil dann poole/share.
warum nicht?Soso, mal angenommen der Benutzer gibt dir ein Key 1,2,3. Dann bist du so schlau und speicherst jetzt 123 in deinen KeyPool. Jetzt kommt von irgendwoher noch eine Anfrage nach dem Wert für den Key 123. Jetzt schaust du also im Keypool nach, ob 123 drin ist und holst den string da raus oder wie?
Leider füllt sich deine Hashmap irgendwann und ist dann genausogroß wie die Datenbank. Das heisst dann brauchst einen Mechanismus, der die gecachten Daten wieder vergisst.
Warum nicht gleich alles einlesen?
Ich hab glaub ich einen Link zu so einem Projekt gepostet, bei dem ich zumindest denke dass sich die Entwickler mehr Überlegungen und Wissen hineingesteckt haben, als du oder ich hier. Du benutzt schließlich auch die vorgefertigte Hashmap und keine selbst zusammengehackte.
Set<Key> pool = MyMap.keySet();
JPA meinst Du? Eins gleich vorweg: 2nd Level Caching ist aber kein Pflichtteil einer JPA 2.0 Implementierung.