Stockage des données dans la mémoire interne (base SQLite
SQLite))
Une application android peut stocker ses données dans la mémoire
interne du téléphone
téléphone. Par défaut
défaut, ces données sont privées; elles sont
inaccessibles à partir d’autres applications. A la suppression de
l’application, ces données seront supprimées.
SQLite est une bibliothèque écrite en langage C qui propose un moteur de
bases de données relationnelle accessible par la langage SQL.
Sa p
particularité est de ne p
pas reproduire
p le schéma habituel client-
serveur, mais d'être directement intégrée aux programmes. L'intégralité
de la base de données (déclarations, tables, index et données) est
stockée dans un fichier indépendant de la plateforme.
Pour son extrême légèreté , SQLite est très populaire sur les systèmes
embarqués, notamment sur la plupart des smartphones modernes ainsi
que les
l systèmes
tè d’
d’exploitation
l it ti mobiles
bil (Symbian
(S bi ett A Android).
d id)
Certaines fonctionnalités standard de SQL ne sont pas reconnues par
SQLite, notamment les contraintes FOREIGN KEY, les transactions
imbriquées, RIGHT OUTER JOIN, FULL OUTER JOIN et certaines variantes
de ALTER TABLE. 125
Stockage des données dans la mémoire interne (base SQLite
SQLite))
Création de la base SQLite
Android
d d ne ffournit aucune base
b de
d ddonnées.
é Pour utiliser
l SQLite, on d
doit
créer notre propre base, puis la remplir avec les tables et les données.
Pour créer et ouvrir une base de données,, la meilleure solution consiste à
créer une sous-classe de SQLiteOpenHelper. Cette classe enveloppe tout
ce qui est nécessaire à la création et à la mise à jour d’une base.
Cette sous-classe aura besoin de trois méthodes :
Un constructeur qui appelle celui de sa classe parente et qui prend en
paramètre le Context (Activity), le nom de la base de données, la fabrique de
curseur (null) et un entier représentant la version du schéma de la base (1)
(1).
onCreate() qui prend en paramètre un objet de type SQLiteDatabase qu’on
désire remplir avec les tables et les données initiales souhaitées.
onUpgrade
U d quii prend
d en paramètre
èt un objet
bj t d
de ttype SQLit
SQLiteDatabase
D t b ainsi
i i que
l’ancien et le nouveau numéro de version. Pour convertir une base d’un
ancien schéma à un nouveau, l’approche la plus simple consiste à supprimer
les anciennes tables et à en créer de nouvelles
nouvelles.
126
Stockage des données dans la mémoire interne (base SQLite
SQLite))
Utilisation
Soit DatabaseHelper
b l une sous-classe
l de
d SQLiteOpenHelper
i l
Création d’une instance de DatabaseHelper
DatabaseHelper dbh = new DatabaseHelper(this); //this : Context
Création d’une instance de SQLiteDatabase
Dans le cas de lecture
SQLiteDatabase db = [Link]();
Dans le cas de modification
SQLiteDatabase db = [Link]();
Le retour de ces instructions sera
return (db==null) ? false : true;
L’instance
L instance db permettra par la suite d’interroger
d interroger et de modifier la base
Lorsqu’on finit de travailler sur cette base, il suffit d’appeler la méthode
close sur l’instance db pour libérer la connexion.
[Link]();
127
Stockage des données dans la mémoire interne (base SQLite
SQLite))
Création des tables et index
Pour créer
é d des tables
bl et ddes index,
d on d
doit appeler
l lla méthode
é h d execSQL()
de l’objet SQLiteDatabase en lui passant l’instruction à exécuter. En cas
d’erreur, cette méthode renvoie null.
Exemple :
Création d’une table constantes avec une colonne de clé primaire _id qui est
un entier incrémenté automatiquement, une colonne titre de type texte et
une colonne valeur de type réel.
[Link](" CREATE TABLE constantes (_id INTEGER PRIMARY KEY
AUTOINCREMENT, titre TEXT, valeur REAL); ");
);
SQLite créera automatiquement un index sur la colonne de clé primaire. Pour
en ajouter d’autres, il suffit d’utiliser CREATE INDEX.
Pour la suppression des tables et des index, il suffit d’utiliser execSQL()
pour les instructions DROP INDEX et DROP TABLE.
128
Stockage des données dans la mémoire interne (base SQLite
SQLite))
Ajout, modification ou suppression des données
Ill existe principalement
l deux
d approches
h pour insérer,
é modifier
df ou
supprimer des données dans une table de la base :
1. Utiliser execSQL
Q
• Exemple
[Link]( "INSERT INTO widgets (name, inventory)"+
VALUES ((’Sprocket’,
"VALUES Sprocket , 5)"
5) );
2. Utiliser insert(), update() et delete() de SQLiteDatabase
• Ces méthodes utilisent des objets ContentValues qui implémentent une
interface qui
q i ressemble à Map avec des méthodes telles q
que
e getAsInteger(),
getAsInteger()
getAsString(), etc.
insert() : elle prend en paramètre le nom de la table, celui d’une colonne
pour l’astuce de la colonne nulle et un objet ContentValues contenant les
valeurs à placer dans la ligne. L’astuce de la colonne nulle est utilisée dans le
cas où l’instance de ContentValues est vide : la colonne indiquée pour cette
astuce recevra alors explicitement la valeur NULL dans l’instruction
l instruction INSERT
produite par insert().
129
Stockage des données dans la mémoire interne (base SQLite
SQLite))
Ajout, modification ou suppression des données
E
Exemple
l
ContentValues cv=new ContentValues();
[Link]([Link], "Gravity, Death Star I");
[Link]([Link], SensorManager.GRAVITY_DEATH_STAR_I);
[Link]("constantes", getNullColumnHack(), cv);
update(): elle prend en paramètre le nom de la table, un objet ContentValues
contenant les colonnes et leurs nouvelles valeurs et, éventuellement, une
clause WHERE et une liste de paramètres qui remplaceront les marqueurs
présents dans celle-ci. Elle n’autorise que des valeurs fixes pour mettre à jour
les colonnes, on devra utiliser execSQL() dans le cas de résultats calculés.
Exemple
e place e ts est u
// remplacements une
e instance
sta ce de Co
ContentValues
te tValues
String[] params=new String[] {"snicklefritz"};
[Link]("widgets", remplacements, "name=?", params);
delete() : prend en paramètres le nom de la table et,
et éventuellement
éventuellement, une
clause WHERE et une liste de paramètres positionnels pour cette clause.
130
Stockage des données dans la mémoire interne (base SQLite
SQLite))
Recherche des données
La solution
l la
l plus
l simple
l consiste à utiliser
l rawQuery en lui
l passant
simplement la requête SELECT. Cette dernière peut contenir des
paramètres positionnels qui seront remplacés par les éléments du tableau
passé en second paramètre. Voici un exemple :
Cursor c=[Link](" SELECT name FROM sqlite_master
WHERE type
type=’table’
table AND name=’constantes’
name constantes ",, null);
Ici, on interroge une table système de SQLite (sqlite_master) pour savoir si la
table constantes existe déjà. La valeur renvoyée est un Cursor qui dispose de
méthodes p permettant de p
parcourir le résultat.
Si les requêtes sont bien intégrées à l’application, c’est une approche
très simple. En revanche, elle se complique lorsqu’une requête comprend
des parties dynamiques que les paramètres positionnels ne peuvent plus
gérer.
131
Stockage des données dans la mémoire interne (base SQLite
SQLite))
Recherche des données
Une autre solution
l consiste à utiliser
l lla méthode
é h d query() qui prend
d en
paramètre les parties d’une instruction SELECT afin de construire la
requête. Ces différentes composantes apparaissent dans l’ordre suivant
dans la liste des paramètres :
1. Le nom de la table interrogée.
2. La liste des colonnes à récupérer.
3. La clause WHERE, qui peut contenir des paramètres positionnels.
4. La liste des valeurs à substituer à ces paramètres positionnels.
5
5. Une éventuelle clause GROUP BY
BY.
6. Une éventuelle clause ORDER BY.
7. Une éventuelle clause HAVING.
À part le nom de la table, ces paramètres peuvent valoir null
String[] colonnes={"ID", "inventory"};
g[] p
String[] params={"snicklefritz"};
{ };
Cursor result=[Link]("widgets", colonnes, "name=?“, params, null, null, null);
132
Stockage des données dans la mémoire interne (base SQLite
SQLite))
Parcourt des résultats
Indépendamment
dé d d
de lla ffaçon d
dont on exécute
é lla requête
ê SELECT, lle
résultat est toujours renvoyé dans un objet de type Cursor (curseur).
Ce curseur offre p
plusieurs méthodes telles q
que :
getCount() qui permet de connaître le nombre de lignes du résultat;
moveToFirst(), moveToNext() et isAfterLast() qui permettent de parcourir
les lignes du résultat;
getColumnNames() qui permet de connaître les noms des colonnes;
getColumnIndex() qui permet de les convertir en numéros de colonnes;
getString(),
tSt i () getInt(),
tI t() etc.
t quii permettent
tt t d’
d’obtenir
bt i lla valeur
l d’
d’une colonne
l
donnée de la ligne courante;
requery() qui permet d’exécuter à nouveau la requête qui a créé le curseur;
close() qui permet de libérer les ressources occupées par le curseur.
133
Stockage des données dans la mémoire interne (base SQLite
SQLite))
Parcourt des résultats
Exemple
l
134
Stockage des données dans la mémoire interne (base SQLite
SQLite))
Exercice
Chargement Sélection d’un contact Recherche d’un contact
135
Stockage des données dans la mémoire interne (base SQLite
SQLite))
Créer les classes :
Contact
int id;
DatabaseHelper
DatabaseHelper(Context)
String name;
onCreate
String phone;
onUpgrade
Contact(id)
addContact(Contact)
Contact(name phone)
Contact(name,
updateContact(Contact)
Contact(id,name,phone)
deleteContact(Contact)
MainActivity
List<Contact> getAllContacts()
onCreate
initialisation()
Créer les fichiers
activity_main.xml
[Link]
136
Stockage des données dans la mémoire interne (base SQLite
SQLite))
Indications :
Pour la
l sélection
él
Ajouter les fichiers :
[Link] sous values [Link] sous drawable
Utiliser la méthode : [Link]([Link]);
Pour la recherche
Utiliser ll’interface
interface OnKeyListener
Modifier la méthode getAllContacts(String motif)
137