Wie Bilder aus DB in SoftReference laden?

Locked

Neues Mitglied
Hi,
ich bin ziemlicher JPA Neuling und möchte meine Swing-Applikation auf EclipseLink umstellen. Nach viel ausprobieren und googeln bin ich auch schon um etliche Erfahrung reicher, stehe aber noch vor der Frage, wie ich Bilder aus einer Datenbank laden kann, so dass sie in der EntityKlasse aber nur durch eine SoftReference erreichbar sind

Konkret sieht es so aus:
Meine Datenbank ist eine JavaDb, in der es unter anderem eine Tabelle pictures:
SQL:
CREATE TABLE pictures (
id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
album_id INTEGER NOT NULL CONSTRAINT pic2album_fk REFERENCES albums(id) ON DELETE CASCADE,
filename VARCHAR(32672) NOT NULL,
thumb BLOB,
PRIMARY KEY (id)
);

In der entity Klasse soll nun das Thumbnail einerseits Lazy initialisiert werden, andererseits soll es nur in einer SoftReference gespeichert werden, da ich nicht alle >10.000 Bilder im Speicher halten kann.

Jetzt stellt sich mir nur die Frage, wie ich das am schlauesten machen kann.
Dass das Bild trotz OneToOne lazy geladen wird, scheint über @OneToOne zu gehen. Aber dann ist das Thumb (als byte array) in der Entity doch fest referenziert, oder? Es sollte ja eigentlich in eine SoftReference wandern, so dass ich auch 10.000 Entities im Speicher halten kann ohne alle Bilder auch halten zu müssen.

Hat da jemand einen Tip für mich?
Besten Dank und Grüße,
locked
 
S

stephanm

Gast
Vorschläge:

1. Separiere die Thumbnaildaten:

CREATE TABLE Picture ( ..., ThumbnailId BIGINT NOT NULL REFERENCES Id OF BigFatBlobTable, ... ) -- Hier KEIN BLOB!
CREATE TABLE BigFatBlobTable ( Id ..., ImageData BLOB NOT NULL ); -- Aber hier!

Also raus mit dem BLOB aus der Picture-Tabelle. So kannst Du 10000 Entities (mit der Referenz auf den BLOB) im Speicher haben, ohne dass alle 10000 BLOBs auch im Speicher sein müssen.

In Java gibts dann ein Lazy-Loaded @OneToOne(fetch = LAZY) von Picture auf BigFatBlobTable - oder eben auch nicht. Jedenfalls musst Du so selbst explizit dafür sorgen, dass der BLOB geladen wird, entweder durch ein DAO oder (bei Lazy Load) durch Zugriff auf den Getter für das byte[].

Vorsicht: Das fetch-Attribut wird i.A. als Hint verstanden, nicht als Anweisung. Die Lösung mit fetch=LAZY ist daher möglicherweise weder portabel noch sicher; es kann zwar funktionieren, ist aber im Prinzip Dummfug.

Das explizite laden der Thumb-Daten über ein DAO ist da schon viel besser, vor allem weil Du hier ggf. einen (LRU-)Cache vor das DAO schalten kannst (vgl.dazu auch Punkt 2).

2. Benutze Memcached

Allgemeines:

Du solltest Dich wirklich ernsthaft fragen, ob es von Vorteil ist, die Picture-Entities (auch ohne BLOB) dauerhaft im Speicher zu haben. Eine ordentliche DB ist bei so einfachen Tabellenstrukturen und überschaubaren Datenmengen von gerade mal 10000 Zeilen in einer Tabelle schnell genug, vorausgesetzt man hat seine Tabellenindizes richtig gesetzt.

Viel Erfolg,

Stephan
 
G

Gelöschtes Mitglied 5909

Gast
Generelle Frage: warum willst du die Bilder in der Datenbank speichern? Das mag bei gewissen Anwendungen Sinn machen,
aber eine Desktop Anwendung gehört immo nicht dazu.

Ich nehme jetzt mal an du willst eine Art Bild-Manager schreiben. Überlege dir doch eine geeignete Verzeichnisstruktur (z.b. Album, id, oder sowas) und lege das ganze auf dem Dateisystem ab.

Dann kannst du ggf. noch eine Schicht drüber ziehen, die es unabhängig vom FileSystem und ähnlichem macht. D.h. du könntest das auch auch auf einem FTP Server speichern, oder einem samba share oder eben in der db.
 

Locked

Neues Mitglied
Hi,

danke für die Antworten!
Ich hatte schon vermutet, dass eine separate Tabelle die Lösung sein würde.

Die Frage, warum die in der DB sein müssen ist durchaus berechtigt. Dabei muss ich zugeben, dass ich in der ganzen JPA-Euphorie ganz vergessen habe, dass es auch reichen könnte, den Dateinamen des Thumbnails in der DB zu speichern. Derzeit sind die Thumbs ja auch nur im Dateisystem ...
Danke! - Dann lasse ich die Bilder wie bisher im Dateisystem und kümmere mich später um eine Zwischenschicht.
 

Ähnliche Java Themen


Oben