AIR SQLite – Enregistrer des objets ActionScript dans une base SQLite
Dans les tutoriaux précédents, on a vu comment créer une base SQLite et la peupler grâce à des instructions INSERT / SELECT. On a aussi vu comment étaient gérées les types de colonnes (par "affinité") et comment stocker des valeurs simples:
AIR SQLite – Création de tables SQLite et types de données
Jusque là, on a stocké des nombres, des String etc., des types assez primitifs. Mais AIR nous donne aussi la possibilité d'aller plus loin en nous permettant de stocker des "Custom Class" (ou Value Object) dans notre base SQLite. Ces custom classes sont des classes que vous avez créé vous-mêmes, des classes métier comme une classe "Contact" par exemple contenant des propriétés que vous avez défini. Vous pouvez donc conserver une liste d'objets Contact directement dans votre base de données.
Attention, si vos objets Contact sont conservés directement en BDD sous forme OBJECT, vous ne pourrez pas effectuer de requête SQL sur l'une des propriétés de l'objet Contact. Vous ne pourrez pas par exemple faire un "WHERE" sur le nom des contacts pour en trouver un.
Création d'une table SQL adéquate
Avant de pouvoir stocker / récupérer vos objets Contact, vous devrez créer une table ayant les bonnes "affinités" sur ses colonnes. Pour stocker un objet ActionScript, il faut donner l'affinité "OBJECT" lors de la définition de votre colonne.
Voici la requête SQL (simpliste) à effectuer pour créer votre table:
CREATE TABLE IF NOT EXISTS contacts (id INTEGER PRIMARY KEY AUTOINCREMENT, data OBJECT)
Insertion de classes ActionScript dans la base
Pour l'insertion, on va se servir des requêtes SQL paramétrées:
AIR SQLite – Utilisation de requête paramétrée (SQLStatement parameters)
Dans notre exemple, on a un tableau d'objet Contact nommé "_contacts". On boucle sur ce tableau et on effectue les enregistrements:
try {
// on commence la transaction
conn.begin();
var q:SQLStatement = new SQLStatement();
q.sqlConnection = conn;
var sql:String = "INSERT INTO contacts (data) VALUES (:data)";
q.text = sql;
for each (var contact:Contact in _contacts) {
q.clearParameters();
q.parameters[":data"] = contact;
q.execute();
}
// on valide la transaction
conn.commit();
} catch (error:SQLError) {
// on annule la transaction entière
conn.rollback();
trace("Error message:", error.message);
trace("Details:", error.details);
}
Récupération des enregistrements (VO)
Maintenant que l'on a réalisé l'insertion, on va simplement récupérer nos VO Contact. Pour faire simple, on va tous les sélectionner, boucler sur le résultat et afficher le nom et l'adresse email de chaque contact:
try {
// on commence la transaction
var q:SQLStatement = new SQLStatement();
q.sqlConnection = conn;
var sql:String = "SELECT * FROM contacts";
q.text = sql;
q.execute();
trace("SELECT OK ");
var sqlResult:SQLResult = q.getResult();
if (sqlResult && sqlResult.data) {
for each (var o:Object in sqlResult.data) {
var c:Contact = Contact(o.data);
trace(c.firstName + " / " + c.email);
}
} else {
trace("Aucun enregistrement, insert data plz");
}
} catch (error:SQLError) {
trace("Error message:", error.message);
trace("Details:", error.details);
}
On lance et là, on a une exception:
TypeError: Error #1034: Type Coercion failed: cannot convert Object@7ef42b1 to vo.Contact.
Hum, que se passe-t-il? Flash essaie d'avoir un objet de type Contact dans le for each mais trouve un Object basique…
En fait, les opérations que nous avons effectués sont bonnes mais il manque une étape. En effet, avant d'enregistrer notre classe en BDD, il faut la référencer pour que Flash Player puisse faire la serialization / deserialization. Cela se fait grâce à la méthode registerClassAlias:
Ajoutons donc cette instruction dans notre code:
private function onAppComplete():void {
registerClassAlias("vo.Contact", Contact);
conn = new SQLConnection();
...
On relance l'opération d'insertion puis de récupération, aucun problème, notre objet Contact est bien un objet de type Contact.
Autre méthode plus élégante
L'ajout de "registerClassAlias" nous permet de résoudre le problème de serialization. Mais ce problème ne se passe pas uniquement avec les objets insérés en BDD. Si vous essayez d'insérer un objet dans un SharedObject, vous aurez le même problème et la même solution.
Un tutorial Flex a déjà été écrit à ce sujet:
Flex Shared Objects – Conserver le type des objets dans un Shared Object avec le metatag RemoteClass
Et la solution donnée dans cette article peut aussi être appliquée au cas SQLite. En effet, il vous suffit d'ajouter le Metatag [RemoteClass] sur votre classe pour que la serialization se fasse sans encombre:
package vo {
[RemoteClass]
public class Contact {
public var id:uint;
.......
Téléchargement du projet
Articles similaires
- AIR SQLite – Utilisation des transactions (begin / commit / rollback) en synchrone
- AIR SQLite – Utilisation de Responder en mode asynchrone
- AIR SQLite – Utilisation des transactions (begin / commit / rollback) en asynchrone
- AIR SQLite – Typer les données renvoyées par un SELECT avec itemClass
- AIR SQLite – Récupérer les données d'une base SQLite (SELECT)
Aucun trackbacks pour l'instant





