Utilisation de SQLite.NET avec Android
La bibliothèque SQLite.NET que Xamarin recommande 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 correspond au mappage relationnel d’objet ( 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 :
- Nom du package : sqlite-net-pcl
- Auteur : Frank A. Krueger
- ID sqlite-net-pcl
- URL : nuget.org/packages/sqlite-net-pcl
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 référentiel praeclarum/sqlite-net.
Une fois que vous disposez de la bibliothèque SQLite.NET disponible, procédez comme suit pour l’utiliser pour accéder à une base de données :
Ajoutez une instruction using : ajoutez l’instruction suivante aux fichiers C# où l’accès aux données est requis :
using SQLite;
Créez 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 du fichier au constructeur de classe SQLiteConnection. Vous n’avez pas besoin de vérifier si le fichier existe déjà. Il sera automatiquement créé si nécessaire, sinon le fichier de base de données existant sera ouvert. La
dbPath
variable doit être déterminée en fonction des règles décrites précédemment dans ce document :var db = new SQLiteConnection (dbPath);
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
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 afficher les résultats sous forme de texte dans la fenêtre principale de l’application.
Android
L’exemple de code suivant montre une interaction complète de base de données à l’aide de la bibliothèque SQLite.NET pour encapsuler l’accès à la base de données sous-jacente. Il montre :
Création du fichier de base de données
Insertion de certaines données en créant des objets, puis en les enregistrant
Interrogation des données
Vous devez inclure ces espaces de noms :
using SQLite; // from the github SQLite.cs class
La dernière nécessite l’ajout de 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);
}
}
L’utilisation de l’attribut [Table]
sans spécifier de paramètre de nom de table entraîne l’utilisation de la table de base de données sous-jacente au même nom que la classe (dans ce cas, « Stock »). Le nom de table réel 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, s’il n’y a pas de colonne, une colonne est ajoutée à la table portant le même nom que la propriété de 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ément 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 lorsqu’une insertion de base de données est tentée. L’utilisation du code doit valider cette opération avant d’insérer l’objet, car cet attribut n’est « vérifié » qu’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 des propriétés que les collections de modèles 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 SQLiteConnection
suivantes peuvent être utilisées pour effectuer d’autres opérations de données :
Insertion : ajoute un nouvel objet à la base de données.
Get<T> : tente de récupérer un objet à l’aide de la clé primaire.
Table<T> : retourne tous les objets de la table.
Delete : supprime un objet à l’aide de sa clé primaire.
Requête<T> : effectuez une requête SQL qui retourne un certain nombre de lignes (en tant qu’objets).
Execute : utilisez cette méthode (et non
Query
) lorsque vous ne vous attendez pas à des lignes de retour à partir de SQL (telles que 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 commençant 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 basé sur l’objet à vos données, vous devrez peut-être effectuer une requête plus complexe que Linq (ou vous aurez peut-être besoin de performances plus rapides). Vous pouvez utiliser des commandes SQL avec la méthode Query, comme illustré ici :
var stocksStartingWithA = db.Query<Stock>("SELECT * FROM Items WHERE Symbol = ?", "A");
foreach (var s in stocksStartingWithA) {
Console.WriteLine ("a " + s.Symbol);
}
Remarque
Lorsque vous écrivez directement des instructions SQL, vous créez une dépendance sur les noms de tables et de 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 les instructions SQL écrites manuellement.
Suppression d’un objet
La clé primaire est utilisée pour supprimer la ligne, comme indiqué ici :
var rowcount = db.Delete<Stock>(someStock.Id); // Id is the primary key
Vous pouvez vérifier 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 : thread unique, 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 thread 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 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
produire une exception SQLite telle que library used incorrectly
, vous devez utiliser la solution de contournement suivante :
Lien vers la bibliothèque libsqlite.so native afin que les API et
sqlite3_initialize
lessqlite3_shutdown
API 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();
Au 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.