Vous avez besoin d'une classe abstraite qui implémente le processus de mise à niveau décrit ici. Ensuite, vous étendez cette classe abstraite pour chacune de vos tables. Dans votre classe abstraite, vous devez stocker vos tables d'une certaine manière (liste, codée en dur). Ainsi, lorsque la fonction onUpgrade se déclenche, vous parcourez les éléments de la table et pour chaque élément de la table, vous suivez les étapes décrites. Ils seront auto-améliorés, en gardant tous leurs détails existants. Notez que l'événement onUpgrade ne se déclenche qu'une seule fois par base de données, c'est pourquoi vous devez parcourir toutes vos tables pour effectuer la mise à niveau de toutes les tables. Vous maintenez seulement 1 numéro de version sur toute la base de données.
- beginTransaction
- terme une création de table avec
if not exists
(nous faisons une mise à niveau, de sorte que le tableau pourrait existe pas encore, il ne parviendra pas modifier et drop)
- mis dans une liste les colonnes existantes
List<String> columns = DBUtils.GetColumns(db, TableName);
- table de sauvegarde (
ALTER table " + TableName + " RENAME TO 'temp_" + TableName
)
- créer un nouveau tableau (le plus récent tableau de schéma de création)
- obtenir l'intersection avec les nouvelles colonnes, ces colonnes de temps prennent n de la table mis à jour (
columns.retainAll(DBUtils.GetColumns(db, TableName));
)
- restaurer les données (
String cols = StringUtils.join(columns, ","); db.execSQL(String.format( "INSERT INTO %s (%s) SELECT %s from temp_%s", TableName, cols, cols, TableName));
)
- table de sauvegarde de suppression (
DROP table 'temp_" + TableName
)
- setTransactionSuccessful
(Cela ne gère pas downgrade de table, si vous renommez une colonne , les données existantes ne sont pas transférées car les noms de colonnes ne correspondent pas).
.
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! Je fais quelque chose de très similaire à toi, mais dans mon cas j'ai besoin de 2 classes dbHelper différentes. Chose est que je reçois une erreur en essayant de le faire. java.lang.IllegalStateException: La classe Helper était de classe X mais essaye d'être réinitialisée à la classe Y. avez-vous déjà rencontré ce problème? – Ajay