SQLiteDatabase Best Practice

  • Hoi Leute,


    hätt grad mal ne best practice Frage:


    Hab mir eine Klasse DB gebaut, erbt von SQLiteOpenHelper, als Singleton implementiert. Habe static Methoden um eine readable oder writeable Instanz zu erhalten und merke mir die Variablen auch static in der Klasse DB. Also rufe ich 2 mal die getReadableInstance auf, kommt dasselbe Objekt zurück und es wird nichts neu instanziiert.
    Ist es jetzt ratsam nach der Verwendung einer z.B. writeable Instanz, diese wieder zu schließen, oder kann ich die einfach offen lassen, weil dann der nächste Zugriff etwas flotter von statten geht? Wie handhabt ihr das?


    Gruß,
    matze

  • Also ich handhabe das gar nicht, da ich mich von den Datenbankinhalten so weit entfernt wie möglich bewegen möchte.


    Im Allgemeinen halte ich schließen und öffnen für die sinnvollste Variante, zumindest, wenn die Datenbank schreibbar geöffnet wurde.
    Meine Paranoia sagt mir nämlich, dass wenn irgendwas schief geht und die Datenbank beschreibbar offen war sie im schlimmsten Fall hin ist.


    Deshalb würde ich so weit es eben möglich ist die ReadOnly-Datenbank offen lassen, die beschreibbare Datenbank jedoch nach Einfügen der Datensätze (was idealerweise als Transaktion durchgeführt wurde) sofort wieder schließen und erneut ReadOnly öffnen.

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Hmmk, dann gibts hier für mich gerade nichts gravierendes zu ändern, denn so habe ich es gerade.
    Mein letztes Projekt hat mich allerdings etwas feinfühliger für Ressourcenverbrauch werden lassen (hatte ja lang mit OutOfMemory bei meinen Thumbnail Generierungen zu kämpfen). Man denkt immer ach das macht doch nicht viel ... wenn man an einem i7 oder zuhause x6 mit 8GB aufwärts hockt stimmt das, aber auf einem Handy nicht ^^
    Nun nachdem mein LogCat manchmal sagt "showStatusIcon on inactive InputConnection" zeigt mir das, dass ich noch feinfühliger werden muss, denn irgendwo hab ich es verpennt etwas zu closen und find es nicht ...


    Auf jeden Fall danke für die Antwort, gibt mir das Gefühl dass meine kleine DB Klasse so im Grunde schon passt ^^


    Gruß,
    matze

  • Tschuldigung wenn ich dazu komme... hab eine kurze frage dazu.


    weiß jemand, wie ich einen Cursor nicht als referenz, sondern als kopie in einen anderen Cursor packen kann?


    z.b.


    Cursor cKontakte = resolver.query(.....)
    .
    .
    .


    Cursor cTemp = cKontakte




    in diesem Fall, wenn ich mit cKontakte.close() den einen Cursor schließe, dann ist in cTemp ja auch nichts mehr drin. Ich brauchs aber so, dass ich cKontakte schließen kann, und der Cursor in cTemp drin bleibt... geht das?

    Bei Unklarheiten, halten Sie Ihren Kopf kurz in eine Schüssel voll klarem Wasser, dann wirds etwas klarer. Danke ;)


    Gruß Andi ---- Das Huhn oder das Ei zuerst? ;)
    Funtik -- G+

  • [matthias]
    Naja, der tatsächliche Speicherverbrauch von so einer geöffneten Datenbank ist ja eher gering. Du hältst einen Pointer darauf und dieser hält irgendwie die Datenbank offen. Da die Datenbank eine Textdatei auf dem Dateisystem ist und nur Abfragen irgendwas in deinen Speicher pumpen, verschwendest du für so eine offen gehaltene Datenbank nicht allzu viel.


    Ich würde ja behaupten, wenn es am Speicher krankt, dann gehe man zunächst die unzähligen neu erstellten Objekte durch und kümmere sich erst im Anschluss (nach etlichen Messungen und so weiter und so fort) um offen gehaltene Referenzen. ;)


    [Funtik]
    Es hängt immer davon ab was genau du brauchst. Einige Objekte implementieren einen Konstruktor, dem du das Objekt mitgibst, welches sie kopieren sollen. (Arrays zum Beispiel).
    Sollte als das nicht klappen (der Cursor kann das gemäß Dokumentation nicht), dann können alle Objekte, die von Object abgeleitet sind, via .clone() eine Kopie erstellen.


    Ich bin wie Matthias auch der Meinung, dass dein Ansatz eventuell nicht der richtige ist.

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Ich lade 5 Cursor, für alle brauche ich nur die .count(). also die Anzahl der Datensätze. nur einer der 5 Cursor soll in der ListView angezeigt werden, deswegen sollen die anderen 4 geschlossen werden.

    Bei Unklarheiten, halten Sie Ihren Kopf kurz in eine Schüssel voll klarem Wasser, dann wirds etwas klarer. Danke ;)


    Gruß Andi ---- Das Huhn oder das Ei zuerst? ;)
    Funtik -- G+

  • Hoi,


    warum holst du dir alle Datensätze, wenn du eh nur die Anzahl brauchst? Ich hol mir doch eigentlich nur das, was ich wissen will, und das ist das count(*), also Anzahl Datensätze. Aber irgendwie glaube ich habe ich dich noch nicht so ganz verstanden, also frag ich mal nach ^^


    Also du holst dir via SQL Daten aus deiner DB. Die liegen im Cursor, also dem klassischen ResultSet. Du hebst nun diesen Cursor dauerhaft auf, anstatt die Daten raus zu ziehen und in was sinnvollem abzulegen oder wie genau?


    Gruß,
    matze

  • Ich habe eine Liste, die mir aus der DB Daten gefiltert anzeigt. Über der Liste sind die Buttons für die Filter. Bei den Buttons steht die Anzahl der DS, die mit dem Filter vorhanden sind.


    Nach jeder Änderung eines Datensatzes muss also die Anzahl bei den Buttons geändert werden und die Liste aktualisiert werden.
    Deswegen lade ich die 5 Cursor, und jenachdem, welcher Filter grad geklickt wurde, sollen dann die Daten in der Liste angezeigt werden und die Anzahl bei den Buttons muss ebenfalls aktualisiert werden.


    Nach diesem ganzen Vorgang möcht ich alle Cursor schließen, bis auf den, der noch angezeigt werden soll...

    Bei Unklarheiten, halten Sie Ihren Kopf kurz in eine Schüssel voll klarem Wasser, dann wirds etwas klarer. Danke ;)


    Gruß Andi ---- Das Huhn oder das Ei zuerst? ;)
    Funtik -- G+

  • Ohne mich jetzt allzu gut mit den Cursorn auszukennen finde ich das sehr seltsam.


    In SQL machst du ja auch kein "SELECT * FROM table" und zählst dann manuell durch.
    Du machst ein "SELECT count(_ID) FROM table' und gut.


    Das müsste doch mit einem SQLiteDatabase.rawQuery("SELECT COUNT(_id) FROM table", null); darzustellen sein.
    Du bekommst dann zwar noch immer einen Cursor zurück, aber eben einen, der ausschließlich die Anzahl der Treffer beinhaltet.
    Und den kannst du dann auch losgelöst von allem anderen Krams wieder schließen.

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Ja im Prinzip habt ihr recht, ich wollte einen DB Zugriff sparen. Da ich sowieso einen der 5 Cursor brauche, um ihn in der Liste anzuzeigen, dachte ich hole ich einfach für jeden alle nötigen Daten. auf meinem SGS2 funktioniert das auch ohne verzögerung. Bloß LogCat zeigt mir immer an, das etliche Cursor nicht geschlossen wurden..


    Ich packe die Daten aus den Cursorn auch in keine Bean(keine Ahnung was das ist). Da der Adapter einen Cursor benötigt um die Daten in der Liste darzustellen.

    Bei Unklarheiten, halten Sie Ihren Kopf kurz in eine Schüssel voll klarem Wasser, dann wirds etwas klarer. Danke ;)


    Gruß Andi ---- Das Huhn oder das Ei zuerst? ;)
    Funtik -- G+

  • Ich verstehe. (nicht ganz, da deine 5 Cursor ja alle dieselben Werte haben und damit die anzuzeigende Zahl immer gleich wäre)


    Genau dafür ist halt Object.clone() da. Du musst dann das Objekt natürlich noch auf den Cursor casten.

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • die Cursor haben ja jeweils unterschiedliche Filter ;)
    Danke,... .clone() klingt schonmal gut. ich probiere es die Tage mal..

    Bei Unklarheiten, halten Sie Ihren Kopf kurz in eine Schüssel voll klarem Wasser, dann wirds etwas klarer. Danke ;)


    Gruß Andi ---- Das Huhn oder das Ei zuerst? ;)
    Funtik -- G+

  • danke für den Hinweis.
    sieht nach einem weiteren Import aus... ich arbeite mit meiner DB durch ContentProvidern

    Bei Unklarheiten, halten Sie Ihren Kopf kurz in eine Schüssel voll klarem Wasser, dann wirds etwas klarer. Danke ;)


    Gruß Andi ---- Das Huhn oder das Ei zuerst? ;)
    Funtik -- G+

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!