Insertion en vrac sur un appareil Android

Je souhaite insérer environ 700 enregistrements dans la firebase database Android lors de ma prochaine mise à niveau. Quel est le moyen le plus efficace de le faire? De divers postes, je sais que si j’utilise des instructions Insert , je devrais les envelopper dans une transaction. Il existe également un article sur l’utilisation de votre propre firebase database, mais j’ai besoin de ces données pour accéder à la firebase database Android standard de mon application. Notez que cela ne se fera qu’une fois par périphérique.

Quelques idées:

  1. Placez un tas d’instructions SQL dans un fichier, lisez-les en une ligne à la fois et exécutez le SQL.

  2. Placez les données dans un fichier CSV ou JSON ou YAML ou XML, etc. Lire une ligne à la fois et faire db.insert() .

  3. Découvrez comment effectuer une importation et effectuer une seule importation du fichier entier.

  4. Créez une firebase database sqlite contenant tous les enregistrements, copiez-la sur le périphérique Android et fusionnez les deux bases de données.

  5. [EDIT] Mettez toutes les instructions SQL dans un seul fichier dans res / values ​​sous la forme d’une grosse chaîne. Puis lisez-les une ligne à la fois et exécutez le SQL.

Quelle est la meilleure façon? Existe-t-il d’autres moyens de charger des données? Est-ce que 3 et 4 sont même possibles?

Je ne crois pas qu’il y ait un moyen réalisable d’accomplir le n ° 3 ou le n ° 4 sur votre liste.

Parmi les autres solutions que vous répertoriez, deux contiennent le fichier de données direct SQL, et l’autre les données au format non SQL.

Tous les trois fonctionneraient très bien, mais la dernière suggestion de saisir les données d’un fichier formaté et de construire le SQL vous-même semble la plus propre. Si une fonctionnalité de mise à jour par lots réelle est ajoutée ultérieurement, votre fichier de données est toujours utilisable ou, du moins, facilement traitable sous une forme utilisable. En outre, la création du fichier de données est plus simple et moins sujette aux erreurs. Enfin, disposer des données “brutes” permettrait d’importer dans d’autres formats de magasin de données.

Dans tous les cas, vous devez (comme vous l’avez mentionné) encapsuler les groupes d’insertions dans les transactions pour éviter la création du journal des transactions par ligne.

Normalement, chaque fois que db.insert() est utilisé, SQLite crée une transaction (et le fichier journal résultant dans le système de fichiers), ce qui ralentit les choses.

Si vous utilisez db.beginTransaction() et db.endTransaction() SQLite ne crée qu’un seul fichier journal sur le système de fichiers, puis valide toutes les insertions en même temps, accélérant ainsi considérablement les choses.

Voici un pseudo-code de: Insertion par lot dans la firebase database SQLite sur Android

 try { db.beginTransaction(); for each record in the list { do_some_processing(); if (line represent a valid entry) { db.insert(SOME_TABLE, null, SOME_VALUE); } some_other_processing(); } db.setTransactionSuccessful(); } catch (SQLException e) {} finally { db.endTransaction(); } 

Si vous souhaitez abandonner une transaction en raison d’une erreur inattendue ou de quelque chose, simplement db.endTransaction() sans d’abord définir la transaction comme réussie ( db.setTransactionSuccessful() ).

Une autre méthode utile consiste à utiliser db.inTransaction() (renvoie true ou false ) pour déterminer si vous êtes actuellement en cours de transaction.

Documentation ici

J’ai trouvé que pour les insertions en bloc, la classe DatabaseUtils.InsertHelper (apparemment peu utilisée) est plusieurs fois plus rapide que l’utilisation de SQLiteDatabase.insert .

Deux autres optimisations ont également consortingbué aux performances de mon application, même si elles ne sont pas toujours appropriées:

  • Ne bind pas les valeurs vides ou null .
  • Si vous êtes certain de pouvoir le faire en toute sécurité, la désactivation temporaire du locking interne de la firebase database peut également améliorer les performances.

J’ai un article de blog avec plus de détails.

Eh bien, ma solution est assez bizarre mais fonctionne très bien … Je comstack une grande quantité de données et les insère en une seule fois (insertion en bloc?)

J’utilise la commande db.execSQL(Query) et je construis la “requête” avec l’instruction suivante …

 INSERT INTO yourtable SELECT * FROM ( SELECT 'data1','data2'.... UNION SELECT 'data1','data2'.... UNION SELECT 'data1','data2'.... UNION . . . SELECT 'data1','data2'.... ) 

Le seul problème est la construction de la requête qui peut être un peu compliquée. J’espère que ça aide

Cet exemple ci-dessous fonctionnera parfaitement

  Ssortingng sql = "INSERT INTO " + DatabaseHelper.TABLE_PRODUCT_LIST + " VALUES (?,?,?,?,?,?,?,?,?);"; SQLiteDatabase db = this.getWritableDatabase(); SQLiteStatement statement = db.comstackStatement(sql); db.beginTransaction(); for(int idx=0; idx < Produc_List.size(); idx++) { statement.clearBindings(); statement.bindLong(1, Produc_List.get(idx).getProduct_id()); statement.bindLong(2, Produc_List.get(idx).getCategory_id()); statement.bindString(3, Produc_List.get(idx).getName()); // statement.bindString(4, Produc_List.get(idx).getBrand()); statement.bindString(5, Produc_List.get(idx).getPrice()); //statement.bindString(6, Produc_List.get(idx).getDiscPrice()); statement.bindString(7, Produc_List.get(idx).getImage()); statement.bindLong(8, Produc_List.get(idx).getLanguage_id()); statement.bindLong(9, Produc_List.get(idx).getPl_rank()); statement.execute(); } db.setTransactionSuccessful(); db.endTransaction();