Partager via


Utilisation de SQLite.NET avec Android

La bibliothèque SQLite.NET recommandée par Xamarin est un ORM très simple qui vous permet de stocker et de récupérer facilement des objets dans la base de données SQLite locale sur un appareil Android. ORM est l’acronyme de Object Relational Mapping, une API qui vous permet d’enregistrer et de récupérer des « objets » à partir d’une base de données sans écrire d’instructions SQL.

Pour inclure la bibliothèque SQLite.NET dans une application Xamarin, ajoutez le package NuGet suivant à votre projet :

SQLite.NET package NuGet

Il existe un certain nombre de packages SQLite différents disponibles. Veillez à choisir le bon package (il peut ne pas s’agir du résultat le plus élevé dans la recherche).

Important

SQLite.NET est une bibliothèque tierce prise en charge à partir du dépôt praeclarum/sqlite-net.

Une fois la bibliothèque SQLite.NET disponible, suivez ces trois étapes pour l’utiliser pour accéder à une base de données :

  1. Ajouter une instruction using : ajoutez l’instruction suivante aux fichiers C# où l’accès aux données est requis :

    using SQLite;
    
  2. Créer une base de données vide : une référence de base de données peut être créée en passant le chemin d’accès au fichier du constructeur de classe SQLiteConnection. Vous n’avez pas besoin de case activée si le fichier existe déjà : il est automatiquement créé si nécessaire, sinon le fichier de base de données existant est ouvert. La dbPath variable doit être déterminée selon les règles décrites plus haut dans ce document :

    var db = new SQLiteConnection (dbPath);
    
  3. Enregistrer des données : une fois que vous avez créé un objet SQLiteConnection, les commandes de base de données sont exécutées en appelant ses méthodes, telles que CreateTable et Insert comme suit :

    db.CreateTable<Stock> ();
    db.Insert (newStock); // after creating the newStock object
    
  4. Récupérer des données : pour récupérer un objet (ou une liste d’objets), utilisez la syntaxe suivante :

    var stock = db.Get<Stock>(5); // primary key id of 5
    var stockList = db.Table<Stock>();
    

Exemple d’accès aux données de base

L’exemple de code DataAccess_Basic pour ce document ressemble à ceci lors de l’exécution sur Android. Le code montre comment effectuer des opérations de SQLite.NET simples et affiche les résultats sous forme de texte dans la fenêtre main de l’application.

Android

Exemple de SQLite.NET Android SQLite.NET

L’exemple de code suivant montre une interaction de base de données entière à l’aide de la bibliothèque SQLite.NET pour encapsuler l’accès à la base de données sous-jacent. Il montre :

  1. Création du fichier de base de données

  2. Insertion de données en créant des objets, puis en les enregistrant

  3. Interrogation des données

Vous devez inclure ces espaces de noms :

using SQLite; // from the github SQLite.cs class

La dernière nécessite que vous ayez ajouté SQLite à votre projet. Notez que la table de base de données SQLite est définie en ajoutant des attributs à une classe (la Stock classe) plutôt qu’à une commande CREATE TABLE.

[Table("Items")]
public class Stock {
    [PrimaryKey, AutoIncrement, Column("_id")]
    public int Id { get; set; }
    [MaxLength(8)]
    public string Symbol { get; set; }
}
public static void DoSomeDataAccess () {
       Console.WriteLine ("Creating database, if it doesn't already exist");
   string dbPath = Path.Combine (
        Environment.GetFolderPath (Environment.SpecialFolder.Personal),
        "ormdemo.db3");
   var db = new SQLiteConnection (dbPath);
   db.CreateTable<Stock> ();
   if (db.Table<Stock> ().Count() == 0) {
        // only insert the data if it doesn't already exist
        var newStock = new Stock ();
        newStock.Symbol = "AAPL";
        db.Insert (newStock);
        newStock = new Stock ();
        newStock.Symbol = "GOOG";
        db.Insert (newStock);
        newStock = new Stock ();
        newStock.Symbol = "MSFT";
        db.Insert (newStock);
    }
    Console.WriteLine("Reading data");
    var table = db.Table<Stock> ();
    foreach (var s in table) {
        Console.WriteLine (s.Id + " " + s.Symbol);
    }
}

Si vous utilisez l’attribut [Table] sans spécifier de paramètre de nom de table, la table de base de données sous-jacente aura le même nom que la classe (dans ce cas, « Stock »). Le nom réel de la table est important si vous écrivez des requêtes SQL directement sur la base de données plutôt que d’utiliser les méthodes d’accès aux données ORM. De même, l’attribut [Column("_id")] est facultatif et, en cas d’absence, une colonne est ajoutée à la table portant le même nom que la propriété dans la classe .

Attributs SQLite

Les attributs courants que vous pouvez appliquer à vos classes pour contrôler leur stockage dans la base de données sous-jacente sont les suivants :

  • [PrimaryKey] : cet attribut peut être appliqué à une propriété entière pour la forcer à être la clé primaire de la table sous-jacente. Les clés primaires composites ne sont pas prises en charge.

  • [AutoIncrement] : cet attribut entraîne l’incrémentation automatique de la valeur d’une propriété entière pour chaque nouvel objet inséré dans la base de données

  • [Column(name)] : le name paramètre définit le nom de la colonne de base de données sous-jacente.

  • [Table(name)] : marque la classe comme pouvant être stockée dans une table SQLite sous-jacente avec le nom spécifié.

  • [MaxLength(value)] : limitez la longueur d’une propriété de texte lors de la tentative d’insertion d’une base de données. Le code de consommation doit valider cela avant l’insertion de l’objet, car cet attribut n’est « vérifié » que lorsqu’une opération d’insertion ou de mise à jour de base de données est tentée.

  • [Ignorer] : provoque l’SQLite.NET d’ignorer cette propriété. Cela est particulièrement utile pour les propriétés qui ont un type qui ne peut pas être stocké dans la base de données, ou les propriétés qui modélisent des collections qui ne peuvent pas être résolues automatiquement par SQLite.

  • [Unique] : garantit que les valeurs de la colonne de base de données sous-jacente sont uniques.

La plupart de ces attributs sont facultatifs. Vous devez toujours spécifier une clé primaire entière afin que les requêtes de sélection et de suppression puissent être effectuées efficacement sur vos données.

Requêtes plus complexes

Les méthodes suivantes sur SQLiteConnection peuvent être utilisées pour effectuer d’autres opérations de données :

  • Insertion : ajoute un nouvel objet à la base de données.

  • Avoir<T> : tente de récupérer un objet à l’aide de la clé primaire.

  • Table<T> : retourne tous les objets de la table.

  • Supprimer : supprime un objet à l’aide de sa clé primaire.

  • Requête<T> : exécutez une requête SQL qui retourne un certain nombre de lignes (en tant qu’objets).

  • Exécuter : utilisez cette méthode (et non Query) lorsque vous n’attendez pas de lignes à partir du sql (par exemple, les instructions INSERT, UPDATE et DELETE).

Obtention d’un objet par la clé primaire

SQLite.Net fournit la méthode Get pour récupérer un objet unique en fonction de sa clé primaire.

var existingItem = db.Get<Stock>(3);

Sélection d’un objet à l’aide de Linq

Les méthodes qui retournent des collections prennent en charge IEnumerable<T> afin que vous puissiez utiliser Linq pour interroger ou trier le contenu d’une table. Le code suivant montre un exemple utilisant Linq pour filtrer toutes les entrées qui commencent par la lettre « A » :

var apple = from s in db.Table<Stock>()
    where s.Symbol.StartsWith ("A")
    select s;
Console.WriteLine ("-> " + apple.FirstOrDefault ().Symbol);

Sélection d’un objet à l’aide de SQL

Même si SQLite.Net pouvez fournir un accès par objet à vos données, vous devrez parfois effectuer une requête plus complexe que linq ne le permet (ou vous aurez peut-être besoin de performances plus rapides). Vous pouvez utiliser des commandes SQL avec la méthode Query, comme indiqué ici :

var stocksStartingWithA = db.Query<Stock>("SELECT * FROM Items WHERE Symbol = ?", "A");
foreach (var s in stocksStartingWithA) {
    Console.WriteLine ("a " + s.Symbol);
}

Notes

Lorsque vous écrivez directement des instructions SQL, vous créez une dépendance sur les noms des tables et des colonnes de votre base de données, qui ont été générées à partir de vos classes et de leurs attributs. Si vous modifiez ces noms dans votre code, vous devez vous rappeler de mettre à jour toutes les instructions SQL écrites manuellement.

Suppression d’un objet

La clé primaire est utilisée pour supprimer la ligne, comme illustré ici :

var rowcount = db.Delete<Stock>(someStock.Id); // Id is the primary key

Vous pouvez case activée pour confirmer le rowcount nombre de lignes affectées (supprimées dans ce cas).

Utilisation de SQLite.NET avec plusieurs threads

SQLite prend en charge trois modes de thread différents : monothread, multithread et sérialisé. Si vous souhaitez accéder à la base de données à partir de plusieurs threads sans aucune restriction, vous pouvez configurer SQLite pour utiliser le mode de threading sérialisé . Il est important de définir ce mode au début de votre application (par exemple, au début de la OnCreate méthode).

Pour modifier le mode de threading, appelez SqliteConnection.SetConfig. Par exemple, cette ligne de code configure SQLite pour le mode sérialisé :

using using Mono.Data.Sqlite;
...
SqliteConnection.SetConfig(SQLiteConfig.Serialized);

La version Android de SQLite présente une limitation qui nécessite quelques étapes supplémentaires. Si l’appel à SqliteConnection.SetConfig génère une exception SQLite telle que library used incorrectly, vous devez utiliser la solution de contournement suivante :

  1. Liez à la bibliothèque libsqlite.so native afin que les sqlite3_shutdown API et sqlite3_initialize soient mises à la disposition de l’application :

    [DllImport("libsqlite.so")]
    internal static extern int sqlite3_shutdown();
    
    [DllImport("libsqlite.so")]
    internal static extern int sqlite3_initialize();
    
  2. Au tout début de la OnCreate méthode, ajoutez ce code pour arrêter SQLite, configurez-le pour le mode sérialisé et réinitialisez SQLite :

    using using Mono.Data.Sqlite;
    ...
    sqlite3_shutdown();
    SqliteConnection.SetConfig(SQLiteConfig.Serialized);
    sqlite3_initialize();
    

Cette solution de contournement fonctionne également pour la Mono.Data.Sqlite bibliothèque. Pour plus d’informations sur SQLite et le multithreading, consultez SQLite et plusieurs threads.