È necessaria una classe astratta che implementa il processo di aggiornamento qui descritto. Quindi estendi questa classe astratta per ciascuna delle tue tabelle. Nella classe astratta è necessario archiviare le tabelle in un modo (elenco, hardcoded), quindi quando onUpgrade esegue l'iterazione sugli elementi della tabella e per ciascun elemento della tabella si eseguono i passaggi descritti. Verranno aggiornati autonomamente, mantenendo tutti i dettagli esistenti. Tieni presente che l'evento onUpgrade si attiva una sola volta per database, ecco perché è necessario scorrere tutte le tabelle per eseguire l'aggiornamento di tutte. Si mantiene solo 1 numero di versione su tutto il database.
- beginTransaction
- corsa creazione tabella con
if not exists
(stiamo facendo un aggiornamento, in modo che la tabella potrebbe non esiste ancora, falliremo alterare e drop)
- messo in una lista le colonne esistenti
List<String> columns = DBUtils.GetColumns(db, TableName);
- tabella di backup (
ALTER table " + TableName + " RENAME TO 'temp_" + TableName
)
- creare nuova tabella (il più recente schema di creazione della tabella)
- ottenere l'incrocio con le nuove colonne, questo colonne prendere tempo n dalla tabella aggiornata (
columns.retainAll(DBUtils.GetColumns(db, TableName));
)
- ripristino dei dati (
String cols = StringUtils.join(columns, ","); db.execSQL(String.format( "INSERT INTO %s (%s) SELECT %s from temp_%s", TableName, cols, cols, TableName));
)
- tabella di backup remove (
DROP table 'temp_" + TableName
)
- setTransactionSuccessful
(Questo non gestisce tavolo downgrade, se si rinomina una colonna , non si ottiene il trasferimento dei dati esistenti poiché i nomi delle colonne non corrispondono).
.
public static List<String> GetColumns(SQLiteDatabase db, String tableName) {
List<String> ar = null;
Cursor c = null;
try {
c = db.rawQuery("select * from " + tableName + " limit 1", null);
if (c != null) {
ar = new ArrayList<String>(Arrays.asList(c.getColumnNames()));
}
} catch (Exception e) {
Log.v(tableName, e.getMessage(), e);
e.printStackTrace();
} finally {
if (c != null)
c.close();
}
return ar;
}
public static String join(List<String> list, String delim) {
StringBuilder buf = new StringBuilder();
int num = list.size();
for (int i = 0; i < num; i++) {
if (i != 0)
buf.append(delim);
buf.append((String) list.get(i));
}
return buf.toString();
}
Hey man! Sto facendo qualcosa di molto simile a te, ma nel mio caso ho bisogno di 2 diverse classi dbHelper. Il fatto è che sto ricevendo un errore mentre cercavo di farlo. java.lang.IllegalStateException: la classe Helper era di classe X ma sta cercando di essere reimpostata sulla classe Y. hai mai dovuto affrontare questo problema? – Ajay