2009-07-13 9 views
21

Non sono sicuro se io sono l'unico che si sente in questo ...Interrogazione e lavorare con i cursori a SQLite su Android

trovo a lavorare con l'API SQLite in Android un dolore completo nel culo e abbastanza anima distruggendo . Qualcuno ha qualche consiglio/aiuto per rendermi la vita più facile?

Ecco un esempio di ciò di cui sto parlando.

//create code 

db.execSQL("CREATE TABLE " + CUSTOMER_TABLE_NAME + " (" 
         + GENERIC_ID_KEY+ " INTEGER PRIMARY KEY NOT NULL, " 
         + PHONE_KEY + " INTEGER NOT NULL, " 
         + CUSTOMER_NAME_KEY+ " TEXT NOT NULL, " 
         + EMAIL_KEY + " TEXT NOT NULL, " 
         + ADDRESS_KEY +" TEXT);"); 


//get code 
    Cursor mCursor = mDb.query(true, CUSTOMER_TABLE_NAME, new String[] {GENERIC_ID_KEY, 
         ADDRESS_KEY, PHONE_KEY, EMAIL_KEY,CUSTOMER_NAME_KEY}, GENERIC_ID_KEY + "=" + customerDbId, null, 
           null, null, null, null); 

     Customer customer = new Customer (customerDbId, (CharSequence)mCursor.getString(mCursor.getColumnIndexOrThrow(CUSTOMER_NAME_KEY)), 
          (CharSequence)mCursor.getString(mCursor.getColumnIndexOrThrow(PHONE_KEY)), 
          (CharSequence)mCursor.getString(mCursor.getColumnIndexOrThrow(EMAIL_KEY)), 
          (CharSequence)mCursor.getString(mCursor.getColumnIndexOrThrow(ADDRESS_KEY))); 

Questo è un semplice esempio di creazione di un oggetto cliente semplice da una query db; parte del mio codice è molto più malvagio di questo. La creazione manuale di query in questo modo porta a tutti i tipi di errori che non trovo fino al runtime.

Qualsiasi consiglio molto apprezzato!

Ok, dopo i suggerimenti di seguito ora ho questo:

db.execSQL("CREATE TABLE customer (_id INTEGER PRIMARY KEY NOT NULL, " 
         + "phone_number INTEGER NOT NULL, " 
         + "name TEXT NOT NULL, " 
         + "email TEXT NOT NULL, " 
         + "address TEXT);"); 


    //get code 
String q = "SELECT * FROM customer WHERE _id = " + customerDbId +";" 
     Cursor mCursor = mDb.rawQuery(q, null); 

     Customer customer = new Customer (mCursor); 

nel cliente, accedo i campi come questo

mName = cursor.getString(2) 

Ahh, mi sento molto meglio :)

Cheers Si

+1

Bene, senza offesa, a volte in realtà devi scrivere del codice :) Le piattaforme mobili non forniscono la stessa astrazione dei sistemi operativi desktop. –

+7

ah, quella cosa 'getColumnIndexOrThrow' mi sta uccidendo ... non potrebbero creare un overload' getString' che prende direttamente il nome della colonna ??? –

risposta

39
  1. Non utilizzare gli oggetti del modello se non è necessario. Ho concluso, a meno che non ci sia una significativa logica aziendale che può essere rappresentata solo tramite oggetti modello, che sono più problemi di quanti ne valga la pena in una piattaforma mobile.
  2. Supponendo di essere bloccati con oggetti modello, farli caricare da un Cursor, anziché tentare di passare in un numero eccessivo di parametri.
  3. query() è molto più dettagliato di rawQuery() per un valore aggiunto limitato, se si conosce SQL.
  4. L'assemblaggio della clausola CREATE TABLE tramite concatenazione è un dolore autoimposto, non richiesto da SQLite o Android.
  5. Non utilizzare getColumnIndexOrThrow() da codice personalizzato. Hai scritto la query, in modo che tu sappia quale ordine le colonne stanno tornando. Utilizza solo qualcosa come getColumnIndexOrThrow() se stai creando una libreria astratta che non conosce i dettagli del Cursore che gli è stato dato.
  6. String eredita da CharSequence, quindi tutti questi modelli possono essere eliminati.
+0

grazie, rawQuery()!Mi era mancato, sembra molto utile. Ripenserò anche agli oggetti del mio modello, dato che non sono bloccato con loro. – longhairedsi

+2

Dove eri qualche settimana fa prima di aver capito tutto questo per me stesso? È bello avere la conferma di ciò che avevo già sospettato, ma è un peccato che tutti i documenti di Google sembrino seguire questa rotta estremamente complessa. –

+0

Hi CommonsWare, puoi confermare la mia comprensione della tua risposta? Stai dicendo che gli oggetti modellati non sono necessari quando si usano dire cursori poiché il cursore è l'oggetto dati e, a meno che non sia necessario manipolare i dati, usare semplicemente il cursore? Sto trovando poco utile per gli oggetti modellati nella mia app con supporto SQLite, come ho modellato le mie tabelle SQLite in "oggetti", e quando restituisco uno come Cursore, è tutto ciò di cui ho bisogno. Sei d'accordo? Se ti interessano maggiori dettagli, questa è la mia domanda: http://stackoverflow.com/questions/9791349/oop-modelled-objects-in-a-database-driven-app – AutoM8R

3

Ho testato un sacco di SQL in SQLite prima di copiarli su Android come stringhe. È più semplice eseguire il debug quando riesco a interagire direttamente con la riga di comando.

Un'altra tecnica che utilizzo è quella di salvare il maggior numero possibile di query come costanti stringa o risorse stringa.

Non è inoltre necessario SQL come INTEGER NOT NULL poiché SQLite utilizza la digitazione di anatra/digitazione manifest. Tuttavia, aiuta l'affinità del tipo.

Problemi correlati