22/11/2023
Institut Supérieur des Etudes Technologiques de Béja
DÉVELOPPEMENT MOBILE
Enseignante: Mme. Haïfa Chorfi
CHAPITRE 6 : Persistance des données
Partie 2 : Base de données SQLite via l’API SQLiteOpenHelper
Niveau : SEM3/DSI3
254 Mme. HAIFA CHORFI
254
Introduction
L’avantage d’une base de données est qu’elle permet de manipuler et de
stocker des données complexes et structurées.
Android fournit un support de bases de données relationnelles au travers
de SQLite.
255 Mme. HAIFA CHORFI
255
Mme Haifa Chorfi 1
22/11/2023
PRÉSENTATION DE SQLITE
SQLite est une base de données relationnelle légère, gratuite et Open
Source.
Pas une architecture client/serveur Accessible via des appels de fonction
de l'application
SQLite s’exécute sans nécessiter de serveur, ce qui implique que
l’exécution des requêtes sur la base de données s’effectue dans le même
processus que l’application.
SQLite est une bibliothèque logicielle qui implémente un moteur de base de
données SQL avec zéro-configuration, léger et sans dépendances externes
Vous pouvez créer plusieurs bases de données par application. Néanmoins,
chaque base de données est dédiée à l’application, c’est-à-dire que seule
l’application qui en est à l’origine pourra y accéder.
256 Mme. HAIFA CHORFI
256
PRÉSENTATION DE SQLITE
SQLite fournit une interface SQL tout en offrant une empreinte mémoire
très réduite et une rapidité de traitement satisfaisante.
L’API de SQLite n’est pas JDBC, qui serait trop lourd pour les terminaux
limités en mémoire comme les téléphones.
Toutes les bases de données sont stockées par défaut dans
/data/data/NOM_PACKAGE_APPLI/databases/Filename sur
votre appareil.
Le fichier de bases de données est automatiquement créé en
MODE_PRIVATE, d’où le fait que seule l’application l’ayant créé peut y
accéder.
Si vous souhaitez exposer les données d’une base de données particulière à
d’autres applications, vous pourrez utiliser un fournisseur de contenu.
257 Mme. HAIFA CHORFI
257
Mme Haifa Chorfi 2
22/11/2023
PRÉSENTATION DE SQLITE
Pour SQLite, il existe les types de données suivants :
NULL pour les données NULL.
INTEGER pour les entiers (sans virgule).
REAL pour les nombres réels (avec virgule).
TEXT pour les chaînes de caractères.
BLOB pour les données brutes.
258 Mme. HAIFA CHORFI
258
CRÉATION ET MISE À JOUR LA BASE DE DONNÉES SQLITE
Le SDK Android offre une classe d’aide : SQLiteOpenHelper.
Cette classe enveloppe tout ce qui est nécessaire à la création et à la mise à
jour d’une base, selon vos spécifications et les besoins de votre application.
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 (une Activity), le nom de la base de données, une
éventuelle fabrique de curseur (le plus souvent, ce paramètre vaudra null)
et un entier représentant la version du schéma de la base (commençant à
1).
259 Mme. HAIFA CHORFI
259
Mme Haifa Chorfi 3
22/11/2023
CRÉATION ET MISE À JOUR LA BASE DE DONNÉES SQLITE
onCreate() : à laquelle vous passerez l’objet SQLiteDatabase qui sera
rempli avec les tables et les données initiales. C'est dans cette méthode
qu’on doit lancer les instructions pour créer la base et éventuellement la
remplir avec des données.
onUpgrade() à laquelle vous passerez un objet SQLiteDatabase ainsi
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.
260 Mme. HAIFA CHORFI
260
CRÉATION ET MISE À JOUR LA BASE DE DONNÉES SQLITE
SQLiteDatabase est la classe de base pour travailler avec une
base de données SQLite sous Android et fournit des méthodes
pour ouvrir, effectuer des requêtes, mettre à jour et fermer la
base de données.
Elle fournie les méthodes pour ouvrir, interroger, modifier ou
fermer une BD : insert(), update() et delete() et la méthode
execSQL(), qui exécute une requête SQL
261 Mme. HAIFA CHORFI
261
Mme Haifa Chorfi 4
22/11/2023
CRÉATION ET MISE À JOUR LA BASE DE DONNÉES SQLITE
Rappel :
La création de table se fait avec la syntaxe suivante :
CREATE TABLE nom_de_la_table (
nom_du_champ_1 type {contraintes},
nom_du_champ_2 type {contraintes},
…);
Pour chaque attribut, on doit déclarer au moins deux
informations :
Son nom, afin de pouvoir l'identifier ;
Son type de donnée.
262 Mme. HAIFA CHORFI
262
CRÉATION ET MISE À JOUR LA BASE DE DONNÉES SQLITE
Rappel :
On trouve comme contraintes :
PRIMARY KEY pour désigner la clé primaire sur un attribut ;
NOT NULL pour indiquer que cet attribut ne peut valoir NULL ;
CHECK afin de vérifier que la valeur de cet attribut est cohérente ;
DEFAULT sert à préciser une valeur par défaut
FOREIGN KEY pour désigner la clé étrangère sur un attribut
263 Mme. HAIFA CHORFI
263
Mme Haifa Chorfi 5
22/11/2023
Exemple :
Création d’une classe d’aide à la création/mise à jour d’une base de données
class MaBaseOpenHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION=1;
private static final String DATABASE_NAME =
“GestionAnimaux";
private static final String TA=“animal";
private static final String C_ID=“_id";
private static final String C_NAME="name";
String REQUETE_CREATION_BD =
"CREATE TABLE " + TA + "(" +
C_ID + "INTEGER PRIMARY KEY AUTOINCREMENT," +
C_NAME + "TEXT)”;
264 Mme. HAIFA CHORFI
264
public MaBaseOpenHelper (Context context,String nom,CursorFactory
cursorfactory, int version){
super(context, nom, cursorfactory, version);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(REQUETE_CREATION_BD);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion) {
db.execSQL("DROP TABLE" + TA+ ";");
onCreate(db);
}
265 Mme. HAIFA CHORFI
265
Mme Haifa Chorfi 6
22/11/2023
CRÉATION ET MISE À JOUR LA BASE DE DONNÉES SQLITE
En utilisant la classe dérivée de SQLiteOpenHelper,
si on veut ouvrir une base alors qu’elle n’existe pas encore, la classe la
créera en appelant la méthode onCreate qu’on doit redéfinir.
Si la version de la base de données a changé, alors la méthode
onUpgrade sera aussi appelée.
266 Mme. HAIFA CHORFI
266
CRÉATION ET MISE À JOUR LA BASE DE DONNÉES SQLITE
Pour accéder à une base de données à l’aide de la classe
SQLiteOpenHelper, on appelle les méthodes getReadableDatabase et
getWritableDatabase et ainsi on obtient une instance de la base de
données respectivement en lecture seule et en lecture/écriture.
Exemple :
MaBaseOpenHelper b = new MaBaseOpenHelper(context,
NOM_BASE_DONNEES, null, VERSION_BASE_DONNEES);
SQLiteDatabase db = b.getWritableDatabase();
...
SQLiteDatabase db = b.getReadableDatabase();
267 Mme. HAIFA CHORFI
267
Mme Haifa Chorfi 7
22/11/2023
ACCÈS À LA BASE DE DONNÉES
Une manière efficace de gérer l'interfaçage avec une base de données est de
proposer des méthodes d’accès et de manipulation simplifiées à la base, et
d’apporter une indépendance vis-à-vis de la source de données.
Ce modèle de conception propose d’offrir au développeur des méthodes
fortement typées pour effectuer des requêtes, insérer, supprimer et mettre
à jour des données de la base mais aussi pour gérer les opérations
d’ouverture et de fermeture de la base de données.
268 Mme. HAIFA CHORFI
268
ACCÈS À LA BASE DE DONNÉES
Ceci implique d'utiliser deux classes :
Une classe (Animal) qui représente les informations et qui peut contenir
un enregistrement d'une table.
Une classe qui effectuera les opérations de gestion d’accès sur la base
(CRUD).
269 Mme. HAIFA CHORFI
269
Mme Haifa Chorfi 8
22/11/2023
Exemple
Pour chaque table de votre base, créer une classe Java pour définir
chaque enregistrement : Il suffit d'avoir un attribut pour chaque attribut
de la table et d'ajouter des méthodes pour y accéder et les modifier
public class Animal {
private int id;
private String name;
public Animal() { }
public Animal(int id, String name){
this.id = id;
this.name = name; }
public int getId() {
return id;}
270 Mme. HAIFA CHORFI
270
public void setId(int id) {
this.id = id;}
public String getName() {
return name;}
public void setName(String name) {
this.name = name;}
}
271 Mme. HAIFA CHORFI
271
Mme Haifa Chorfi 9
22/11/2023
Exemple : CRUD
Pour chaque table, créer une classe Java pour gérer l’accès aux données : On
doit y inclure au moins les méthodes CRUD, autrement dit les méthodes qui
permettent l'ajout d'entrées dans la base, la récupération d'entrées, la mise à
jour d'enregistrements ou encore la suppression de tuples. De plus, on
rajoute les constantes globales déclarées précédemment dans la base :
private SQLiteDatabase maBase;
private MaBaseOpenHelper baseHelper;
272 Mme. HAIFA CHORFI
272
public long insertAnimal(Animal a) {
// Insérer le code d’insertion.
}
public int updateAnimal(int id, Animal a) {
// Insérer le code de mise à jour de la base.
}
public boolean removeAnimal(String name) {
// Insérer le code de suppression.
}
public boolean removeAnimal(int id) {
// Insérer le code de suppression.}}
273 Mme. HAIFA CHORFI
273
Mme Haifa Chorfi 10
22/11/2023
INSERTION DES DONNÉES
Insérer ou mettre à jour des données dans une base SQLite
repose sur l’utilisation de la méthode insert de la classe
SQLiteDatabase.
Syntaxe:
long insert(String table, String nullColumnHack, ContentValues
values) : renvoie le numéro de la ligne ajoutée.
table est l'identifiant de la table dans laquelle insérer l'entrée.
nullColumnHack est le nom d'une colonne à utiliser au cas où vous
souhaiteriez insérer une entrée vide. Prenez n'importe laquelle.
values est un objet qui représente l'entrée à insérer. Cet objet stocke les
valeurs de chaque colonne de la ligne à insérer sous la forme d’une
collection d’associations entre le nom de la colonne et la valeur.
274 Mme. HAIFA CHORFI
274
INSERTION DES DONNÉES
Exemple :
...
ContentValues values = new ContentValues();
values.put(C_ID,Animal.getId());
values.put(C_NAME,Animal.getName());
db.insert(TA,null,values);
...
Remarque : Vous pouvez aussi utiliser la méthode execSQL en spécifiant
une requête SQL standard INSERT pour arriver au même résultat.
L’utilisation de la méthode insert permet de faciliter l’action en proposant
une approche objet.
275 Mme. HAIFA CHORFI
275
Mme Haifa Chorfi 11
22/11/2023
MISE À JOUR DES DONNÉES
Pour mettre à jour des données dans SQLite, utilisez la méthode update de
la classe SQLiteDatabase en spécifiant un objet ContentValues contenant les
nouvelles valeurs et la valeur de la clause de condition WHERE.
Syntaxe :
int update(String table, ContentValues values, String whereClause, String[]
whereArgs).
Exemple :
...
ContentValues values = new ContentValues();
values.put(C_Name, Animal.getName());
db.update(TA, values, C_ID + " = ? " , new String[]{"4"});
...
276 Mme. HAIFA CHORFI
276
SUPPRESSION DES DONNÉES
Pour supprimer des données d’une table, utilisez la méthode delete de la classe
SQLiteDatabase en spécifiant le nom de la table ciblée et le critère permettant à la
base d’identifier les éléments à supprimer.
Syntaxe :
int delete(String table, String whereClause, String[] whereArgs) : L'entier renvoyé
est le nombre de lignes supprimées.
table est l'identifiant de la table.
whereClause correspond au WHERE en SQL.
whereArgs est un tableau des valeurs qui remplaceront les « ? » dans whereClause.
Exemple :
...
db.delete(TA, C_Name + " LIKE ?", new String[]{name});
...
277 Mme. HAIFA CHORFI
277
Mme Haifa Chorfi 12
22/11/2023
REQUÊTE DANS UNE BASE SQLITE
On peut utiliser plusieurs approches pour récupérer les données d’une base
SQLite avec SELECT :
rawQuery() permet d’exécuter directement une instruction SELECT.
query() permet de construire une requête à partir de ses différentes
composantes.
278 Mme. HAIFA CHORFI
278
REQUÊTE DANS UNE BASE SQLITE
Requêtes brutes
La solution la plus simple, au moins du point de vue de l’API, consiste à
utiliser rawQuery() en lui passant simplement la requête SELECT.
Exemple :
Cursor c=db.rawQuery("SELECT name FROM animal
WHERE name like ’a*’, null);
Ici, nous interrogeons une table système de SQLite (sqlite_master) pour
savoir si la table TABLE_Animal existe déjà.
La valeur renvoyée est un Cursor qui dispose de méthodes permettant de
parcourir le résultat.
279 Mme. HAIFA CHORFI
279
Mme Haifa Chorfi 13
22/11/2023
REQUÊTE DANS UNE BASE SQLITE
Requêtes normales
Toutes les requêtes de sélection SQLite s’effectuent via la méthode query
d’une instance de SQLiteDatabase. Cette méthode retourne un curseur
permettant ensuite de naviguer dans les résultats.
À la différence de nombreuses API pour d’autres bases de données, les
requêtes de sélection ne se font pas à partir de SELECT mais par
l’utilisation de la méthode query – et de ses surcharges – proposant
directement les critères de sélection au développeur.
La requête de sélection SQL sera construite par la méthode, puis compilée
pour interroger la base de données.
Les paramètres de la requête sont donc très proches d’une requête
SELECT standard
280 Mme. HAIFA CHORFI
280
281 Mme. HAIFA CHORFI
281
Mme Haifa Chorfi 14
22/11/2023
REQUÊTE DANS UNE BASE SQLITE
Syntaxe :
Cursor query(String table, String[] columns, String selection,
String[] selectionArgs, String groupBy,
String having, String orderBy, String limit);
Exemple:
Cursor result=db.query("TA", new String[]{"ID", "NAME" },
"ID>? AND name like ?",new String []{"4", "Chien"}, null,
null, null,null);
282 Mme. HAIFA CHORFI
282
REQUÊTE DANS UNE BASE SQLITE
Curseurs
Quelle que soit la façon dont vous exécutez la requête, vous obtiendrez un
Cursor en retour.
Les curseurs sont des objets qui contiennent les résultats d'une recherche
dans une base de données. Ce sont en fait des objets qui fonctionnent
comme les, ils contiennent les colonnes et lignes qui ont été renvoyées par
la requête.
283 Mme. HAIFA CHORFI
283
Mme Haifa Chorfi 15
22/11/2023
284 Mme. HAIFA CHORFI
284
REQUÊTE DANS UNE BASE SQLITE
Pour parcourir un curseur, les méthodes de navigation dans le curseur
renvoient des booléens qui valent true si l'opération s'est déroulée avec
succès, ou false auquel cas la ligne demandée n'existe pas.
Syntaxe en utilisant While:
while (cursor.moveToNext()) {
// instructions }
cursor.close();
Syntaxe en utilisant for:
for(cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToNe
xt()) { // instructions }
cursor.close();
285 Mme. HAIFA CHORFI
285
Mme Haifa Chorfi 16
22/11/2023
Exercice
On désire créer une application permettant de gérer les planètes stockées
dans une base de données SQLite.
1.Créer la classe Planète qui représente un enregistrement de la table Planete
(ID, Nom, Rayon).
2.Créer la classe d’aide MaBaseOpenHelper permettant de créer la base
« Galaxie.db » contenant une table Planete (ID, Nom, Rayon).
3. Mettre à jour la classe MaBaseOpenHelper implémentant les méthodes
d’accès à la base de données « galaxie.db » et de manipulation de la table
« Planete ».
286 Mme. HAIFA CHORFI
286
Exercice
287 Mme. HAIFA CHORFI
287
Mme Haifa Chorfi 17
22/11/2023
Solution
288 Mme. HAIFA CHORFI
288
Solution
289 Mme. HAIFA CHORFI
289
Mme Haifa Chorfi 18
22/11/2023
Solution
290 Mme. HAIFA CHORFI
290
Solution
291 Mme. HAIFA CHORFI
291
Mme Haifa Chorfi 19
22/11/2023
Exercice
292 Mme. HAIFA CHORFI
292
Mme Haifa Chorfi 20