Avez-vous une question? (216) 97 656 803 hajjriadh@gmail.com
Flutter

Flutter SQLite : Opérations CRUD

Un cours complet pour maîtriser Flutter SQLite : Opérations CRUD.

0 chapitres 0 QCM Accès gratuit

Flutter SQLite : Opérations CRUD

Flutter SQLite : Opérations CRUD

  1. Étapes pour utiliser SQLite dans Dart’s Flutter

  2. Résumé
  3. Voici les étapes requises pour utiliser SQLite dans votre application Flutter.
    • Étape 1: Importation sqflite
      • Vous devez d’abord commencer par importer sqflite dans votre projet. Ouvrez le fichier et ajoutez la ligne suivante :pubspec.yaml
      • dependencies:
          flutter:
            sdk: flutter
          path_provider: ^2.1.0 
          path: ^1.6.4 
          sqflite: ^2.3.0
      • Path_provider permet de trouver les chemins ou emplacements couramment utilisés sur le système de fichiers.
      • Path est utile dans les opérations permettant la manipulation de chemins ou d’emplacements.
      • Ensuite, exécutez flutter pub get dans le terminal pour installer la dépendance.
      • Vous pouvez trouver les versions actuelles de ces packages ici : ou tapez:
        flutter pub upgrade --major-versions
      • Après cela, vous êtes prêt à utiliser SQLite dans votre application Flutter.sqflite
    • Étape 2: Création et ouverture de la base de données
      • Ensuite, vous devez créer et ouvrir une base de données à l’aide de la méthode fournie. Par exemple:openDatabase()
      • createDatabase() async {
          String databasesPath = await getDatabasesPath();
          String dbPath = join(databasesPath, 'my.db');
        
          var database = await openDatabase(dbPath, version: 1, onCreate: populateDb);
          return database;
        }
      • Paramètres de la méthode:
        • 'databasesPath' est la variable qui contient le chemin du répertoire où vous souhaitez stocker votre base de données. Vous avez obtenu ce chemin en appelant 'getDatabasesPath()'.
        • 'getDatabasesPath()' est une fonction asynchrone qui renvoie un 'Future'. Un 'Future' représente une valeur qui sera disponible à un moment donné dans le futur. Dans ce cas, la valeur future est une chaîne de caractères (le chemin du répertoire de la base de données).
        • En utilisant 'await', vous attendez que le 'Future' retourné par 'getDatabasesPath()' soit résolu, c’est-à-dire que la valeur du chemin soit récupérée avant de continuer l’exécution du reste du code dans la fonction 'createDatabase()'.
        • La fonction 'join()' est utilisée pour concaténer deux éléments, c’est-à-dire 'databasesPath' et ''my.db'', pour créer un chemin complet vers le fichier de la base de données. Cette fonction est souvent utilisée pour s’assurer que le chemin est correctement formaté selon les conventions du système d’exploitation sur lequel votre application s’exécute.
        • Enfin, le chemin complet du fichier de base de données ('dbPath') est utilisé pour ouvrir ou créer la base de données SQLite en utilisant la fonction 'openDatabase()'.
        • L’utilisation de 'await' dans cette situation est importante car elle garantit que le chemin du répertoire de la base de données est récupéré correctement avant d'ouvrir la base de données. Cela évite les erreurs potentielles liées à l’accès au système de fichiers asynchrone.
        • dbPath: chemin d’accès complet au fichier de base de données SQLite.
        • version: numéro de version de la base de données. Ceci est utilisé pour gérer les modifications de schéma de base de données dans les futures mises à jour d’application.
        • onCreate: fonction de rappel exécutée si la base de données n’existe pas encore (c’est-à-dire qu’elle est créée pour la première fois). Le but de ce rappel est généralement de définir le schéma initial et de remplir la base de données avec des tables et des données initiales.populateDb
    • Étape 3: Création de la ou des tables de base de données
      • Vous devez ensuite définir la fonction que vous avez spécifiée comme rappel :populateDb()
      • void populateDb(Database database, int version) async {
          await database.execute("CREATE TABLE Customer ("
                  "id INTEGER PRIMARY KEY,"
                  "first_name TEXT,"
                  "last_name TEXT,"
                  "email TEXT"
                  ")");
        }
      • Dans la fonction de rappel, nous exécutons notre première requête sur la base de données qui nous permet de créer une table appelée avec quatre colonnes. Customer
      • Vous pouvez bien sûr créer autant de tables que vous le souhaitez et définir des relations entre elles pour créer le schéma de base de données souhaité.
      • Utiliser Batch
        • Dans sqflite, on peut exécuter plusieurs requêtes SQL dans un batch pour optimiser les performances. Un batch permet d'exécuter plusieurs opérations en une seule transaction, ce qui est plus rapide que de les exécuter une par une.
        • Un Batch est un mécanisme qui permet d'exécuter plusieurs requêtes SQL (INSERT, UPDATE, DELETE) en une seule transaction. Cela permet d'améliorer la performance et la fiabilité des opérations sur la base de données.
        • Comment utiliser un Batch dans sqflite ?
        • Dans Flutter, on utilise la méthode .batch() pour regrouper plusieurs opérations.
        • 1️⃣ Création d'un Batch
          Batch batch = db.batch();
          2️⃣ Ajout des requêtes dans le Batch
          batch.insert('table', {'colonne1': 'valeur1', 'colonne2': 'valeur2'});
          batch.update('table', {'colonne1': 'nouvelle_valeur'}, where: 'id = ?', whereArgs: [1]);
          batch.delete('table', where: 'id = ?', whereArgs: [2]);
          3️⃣ Exécution du Batch
          await batch.commit();
        Si vous souhaitez créer plusieurs tables à la fois, vous devrez appeler database.execute pour chaque instruction de création de table que vous souhaitez exécuter.
        void populateDb(Database database, int version) async {
          // Create the Customer table
          await database.execute("CREATE TABLE Customer ("
              "id INTEGER PRIMARY KEY,"
              "first_name TEXT,"
              "last_name TEXT,"
              "email TEXT"
              ")");
        
          // Create another table (example)
          await database.execute("CREATE TABLE Order ("
              "order_id INTEGER PRIMARY KEY,"
              "customer_id INTEGER,"
              "order_date TEXT,"
              "total_amount REAL"
              ")");
          
          // Create more tables as needed
        }
      • Vous pouvez regrouper plusieurs instructions SQL dans un seul 'Batch', ce qui peut être plus efficace en termes de performances car elles sont exécutées en une seule transaction.
      • Toutes les instructions dans le 'Batch' sont exécutées ensemble, et si l’une d’entre elles échoue, toutes les modifications sont annulées (tout ou rien). Cela garantit la cohérence de la base de données.
      • void populateDb(Database database, int version) async {
          Batch batch = database.batch();
          
          batch.execute("CREATE TABLE Customer ("
              "id INTEGER PRIMARY KEY,"
              "first_name TEXT,"
              "last_name TEXT,"
              "email TEXT"
              ")");
          
          // Vous pouvez ajouter d'autres opérations Batch si nécessaire
          
          await batch.commit();
        }
        Si vous souhaitez créer plusieurs tables à la fois.
        void populateDb(Database database, int version) async {
          Batch batch = database.batch();
          
          // Create the Customer table
          batch.execute("CREATE TABLE Customer ("
              "id INTEGER PRIMARY KEY,"
              "first_name TEXT,"
              "last_name TEXT,"
              "email TEXT"
              ")");
          
          // Create another table (example)
          batch.execute("CREATE TABLE Order ("
              "order_id INTEGER PRIMARY KEY,"
              "customer_id INTEGER,"
              "order_date TEXT,"
              "total_amount REAL"
              )");
        
          // Add more table creation statements in the same batch if needed
        
          await batch.commit();
        }
    • Étape 4: Ajout d'un ou des modèles de données
      • Avant de créer les opérations CRUD, nous devons ajouter un modèle. Créez un fichier et ajoutez la classe suivante :lib/model/customer.dart comme exemple
      • class Customer {
          int id;
          String firstName;
          String lastName;
          String email;
        
          Customer({
            this.id,
            this.firstName,
            this.lastName,
            this.email,
          });
        
          factory Customer.fromMap(Map map) {
            return Customer(
              id: map['id'],
              firstName: map['first_name'],
              lastName: map['last_name'],
              email: map['email'],
            );
          }
        }
        
      • Si votre base de données contient plusieurs tables à la fois, vous pouvez créer un modèle pour chaque table ou les mettre dans un seul.
      • En règle générale, si votre application est petite à moyenne avec quelques tables, vous pouvez regrouper les modèles dans un seul fichier. Cela simplifie la gestion. Cependant, si votre application est grande et complexe avec de nombreuses tables, il peut être préférable d’utiliser des fichiers séparés pour chaque modèle afin de maintenir une meilleure organisation.
      • Dans le fichier déjà crée ajoutez la classe suivante :lib/model/order.dart comme exemple
      • class Order {
          int orderId;
          int customerId;
          String orderDate;
          double totalAmount;
        
          Order({
            this.orderId,
            this.customerId,
            this.orderDate,
            this.totalAmount,
          });
        
          factory Order.fromMap(Map<String, dynamic> map) {
            return Order(
              orderId: map['order_id'],
              customerId: map['customer_id'],
              orderDate: map['order_date'],
              totalAmount: map['total_amount'].toDouble(),
            );
          }
        }
    • Étape 5 : Ajout de méthodes CRUD
      • Vous pouvez utiliser différentes approches pour exécuter des opérations CRUD : les RawSQLrequêtes ou une API de haut niveau.
      1. Étape 5.1 : Implémentation de l'opération Create
        • Vous pouvez utiliser différentes approches pour exécuter des opérations CRUD : les requêtes ou une API de haut niveau. RawSQL
        • Commençons par une méthode pour créer un customer dans la table de base de données :
        • Première approche : utiliser la méthode insert()
            Future<int> createCustomer(Customer customer) async {
              var result = await database.insert("Customer", customer.toMap());
              return result;
            }
          • Comme vous pouvez le voir, nous convertissons simplement notre objet customer en map (en utilisant la méthode que nous avons définie dans le modèle) et nous le passons à la méthode qui prend le nom de la table comme premier paramètre et les données comme second paramètre. toMap()Customerinsert()
        • Deuxième approche : utiliser la méthode rawInsert()
          • La méthode rawInsert() est une méthode sqflite pour Flutter, qui permet d’insérer des données directement sous forme de requête SQL brute dans une base de données.
          • createCustomer(Customer customer) async {
                var result = await database.rawInsert(
                  "INSERT INTO Customer (id,first_name, last_name, email)"
                  " VALUES (${customer.id},${customer.firstName},${customer.lastName},${customer.email})");
                return result;
              }

      2. Étape 5.2 : Implémentation de l'opération Read (All)

        • Maintenant, implémentons l'opération de lecture de CRUD,
        • Première approche: utiliser la méthode query()
          • La méthode query() est une abstraction de haut niveau qui prend le nom de la table et les colonnes renvoient ensuite des données.
          • Future<List> getCustomers() async {
              var result = await database.query("Customer", columns: ["id", "first_name", "last_name", "email"]);
            
              return result.toList();
            }
          • Nous utilisons la méthode List pour convertir le jeu de résultats en Flutter .toList()
        • Deuxième approche : utiliser la méthode rawQuery()
          • La méthode 'rawQuery sqflite pour Flutter, qui permet d’exécuter des requêtes SQL brutes dans une base de données et de récupérer les résultats sous forme de liste de résultats (généralement une liste de maps).
          • Future<List> getCustomers() async {
              var result = await database.rawQuery('SELECT * FROM Customer');
              return result.toList();
            }
          • Avec la méthode, il vous suffit de passer la requête SELECT brute.rawQuery()
      3. Étape 5.3 :Implémentation de l’opération Read(by Id)

        • Après avoir obtenu tous les customer de la base de données, nous devons maintenant obtenir un seul customer par son identifiant.
        • Première approche : utiliser la méthode query()
          • Tout comme l’exemple précédent, nous utilisons la méthode de requête pour obtenir des données à partir d’une table.
          • Nous spécifions la table comme premier paramètre, les colonnes comme deuxième paramètre et cette fois nous ajoutons également un paramètre Where qui prend la clause WHERE et un tableau WhereArgs pour passer les arguments Where.
          • Future<Customer> getCustomer(int id) async {
              List<Map> results = await db.query("Customer",
                  columns: ["id", "first_name", "last_name", "email"],
                  where: 'id = ?',
                  whereArgs: [id]);
            
              if (results.length > 0) {
                return new Customer.fromMap(results.first);
              }
            
              return null;
            }
          • Nous voulons obtenir un client par id = ? donc nous passons une clause. Le symbole sera ? remplacé par la valeur réelle du paramètre whereArgs
        • Deuxième approche : utiliser la méthode rawQuery()
            Future<Customer> getCustomer(int id) async {
              var results = await database.rawQuery('SELECT * FROM Customer WHERE id = $id');
            
              if (results.length > 0) {
                return new Customer.fromMap(results.first);
              }
            
              return null;
            }
      4. Étape 5.4 :Implémentation de l’opération de mise à jour (Update)
        • Maintenant, implémentons l’opération de mise à jour en utilisant les deux approches.
        • Première approche: utiliser la méthode update()
          • La méthode est similaire à la méthode, mais pour la mise à jour des données :update()query()
          • Future<int> updateCustomer(Customer customer) async {
              return await database.update("Customer", customer.toMap(), where: "id = ?", whereArgs: [customer.id]);
            }
          • Nous transmettons le nom de la table, les données client sous forme de carte, la clause WHERE et les arguments WHERE.
        • Deuxième approche; Utilisation de la méthode rawUpdate()
          • La méthode rawUpdate() est utilisée pour exécuter une requête UPDATE brute sur la base de données :
          • Future<iint> updateCustomer(Customer customer) async {
              return await database.rawUpdate(
                  'UPDATE Customer SET first_name = ${customer.firstName} WHERE id = ${customer.id}'
              );
            }

        Étape 5.5 :Implémentation de l’opération de suppression (Delete)

        • Enfin, nous devons implémenter l'opération de suppression de notre exemple CRUD. Cela peut également être fait en suivant deux approches :
        • Première approche : utilisation de la méthode delete()
          • La méthode delete() prend un nom de table, la clause WHERE et les arguments WHERE :
          • Future<int> deleteCustomer(int id) async {
              return await database.delete("Customer", where: 'id = ?', whereArgs: [id]);
            }
        • Deuxième approche; Utilisation de la méthode rawDelete()
          • La méthode rawDelete() prend une requête DELETE brute :
          • Future<int> deleteCustomer(int id) async {
              return await db.rawDelete('DELETE FROM Customer WHERE id = $id');
            }
    • Étape 06: Fermer la base de données
      • Une fois la base de données terminée, vous pouvez exécuter la méthode suivante pour la fermer:
      • await database.close();