Bonjour,
Dans mon application, j'ai une table (SQLite) qui est utilisée par une de mes classes qui étend CursorAdapter, afin de remplir une ListView. De plus, il y a un petit EditText (+ TextWatcher) au dessus de la ListView afin de filtrer la liste (effectue donc des Select à chaque fois que l'EditText est modifié). Toute cette partie marche bien.
Cependant, j'aimerais pouvoir mettre à jour cette table à tout moment et je ne sais pas encore comment m'y prendre, en évitant surtout les problèmes d'accès multiples.
J'ai d'abord pensé à faire un Service, qui téléchargerait puis parserait un xml sur un serveur web, dans le but de récupérer les données qu'il faudra mettre à jour dans la table.
Par ailleurs, étant donné qu'il y a beaucoup d'insertions à faire lors des mises à jour, j'utilise actuellement des requêtes préparées ET j'exécute tout ça en une seule transaction.
Pour expliquer le code ci-dessous, mon AsyncTask ouvre la base de données, utilise la méthode beginInsertStatement (qui démarre une transaction et compile la requête préparée), utilise preparedInsert pour chaque ligne, puis termine avec endInsertStatement pour fermer la requête préparée et la transaction.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 public void beginInsertStatement() { this.sqliteDatabase.beginTransaction(); this.statement = this.sqliteDatabase.compileStatement("INSERT INTO " + TABLE_NAME + " VALUES(?,?,?)"); } public void preparedInsert(String id, String name, String lib) { this.statement.bindString(1, id); this.statement.bindString(2, name); this.statement.bindString(3, lib); this.statement.executeInsert(); this.statement.clearBindings(); // clearBindings nécessaire ? } public void endInsertStatement() { this.statement.close(); this.sqliteDatabase.setTransactionSuccessful(); this.sqliteDatabase.endTransaction(); }
Autre point, je n'ai qu'une seule instance de ma classe SQLiteOpenHelper :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 public class DatabaseHelper extends SQLiteOpenHelper { private static DatabaseHelper mHelperInstance = null; public static synchronized DatabaseHelper getHelperInstance(Context context) { if (mHelperInstance == null) { mHelperInstance = new DatabaseHelper(context.getApplicationContext()); } return mHelperInstance; }
Q1 : j'aimerais savoir si l'utilisation d'un Service pour télécharger et mettre à jour la table n'est pas "mauvaise", et s'il existe des moyens plus efficaces/plus propre ?
Q2 : est-ce qu'il peut y avoir des problèmes si le Service met à jour la table (étant donné que la màj est effectuée en une transaction), pendant que l'utilisateur parcours la ListView / effectue des select avec le filtre ?
Q2.5 : si le fait de tout faire en une transaction évite les problèmes avec le CursorAdapter/ListView, il faudrait que j'effectue la "vidange" de la table dans cette même transaction ? Est-ce que, pour le coup, ça poserait des problèmes aux insert effectués juste après ?
Q3 : pour l'instant, à chaque mise à jour, je vide la table et je fais tout plein d'insert (environ 3000). Sachant que ce sera à 90% de l'update et non de l'insert, sauf la première fois où c'est de l'insert à 100%, est-ce qu'il y a un moyen plus efficace (en terme de performance), comme faire une requête "UPSERT" (Insert or replace ... / insert ... on duplicate key update ...) ?
[EDIT Q3] : Je viens d'y penser à l'instant, mais je pense être obligé de vider la table car, lorsqu'il y a des données qui sont dans la table mais plus dans le xml, elles doivent être supprimées.
Merci d'avance.
Partager