Utiliser SQLite avec Android

Nous allons aujourd’hui apprendre à utiliser la base de données SQLite au travers d’une application Android. Pour cela, nous prendrons l’exemple d’une liste de contacts que l’on souhaite enregistrer en base de données.

La classe Contact

Nous allons commencer par réfléchir aux différentes données que nous souhaitons voir apparaitre dans la base de données.

Tout d’abord nous aurons besoin de créer un objet Contact comprenant 4 attributs :

  • id : l’identifiant du contact dans la base de données
  • nom : le nom du contact dans la base de données
  • prénom : le prénom du contact dans la base de données
  • numéro de téléphone : le numéro de téléphone du contact dans la base de données

Nous prendrons alors bien soin de créer des getters et des setters pour chacun de ces attributs.

package com.yoannzimero.sqlite.example;

public class Contact {

	private int id;

	private String nom;

	private String prenom;

	private String numeroTelephone;

	public Contact() {

	}

	public Contact(String nom, String prenom, String numeroTelephone) {
		super();
		this.nom = nom;
		this.prenom = prenom;
		this.numeroTelephone = numeroTelephone;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getNom() {
		return nom;
	}

	public void setNom(String nom) {
		this.nom = nom;
	}

	public String getPrenom() {
		return prenom;
	}

	public void setPrenom(String prenom) {
		this.prenom = prenom;
	}

	public String getNumeroTelephone() {
		return numeroTelephone;
	}

	public void setNumeroTelephone(String numeroTelephone) {
		this.numeroTelephone = numeroTelephone;
	}

	@Override
	public String toString() {
		return "[Contact] id : " + id + " - nom , prenom : " + nom + ", "
				+ prenom + " - numero de téléphone : " + numeroTelephone;
	}

}

Nous venons alors de créer notre objet Contact que nous utiliserons par la suite pour manipuler notre base de données.

Nous remarquerons que nous avons surchargé la méthode toString(), de manière à pouvoir visualiser par la suite l’ensemble des données du contact dans un Toast.

Définition de la table Contacts

Nous allons alors définir la classe qui permettra de créer la base de données ainsi que la table qui contiendra les contacts.

Pour cela, nous allons définir une classe MySQLiteDatabase qui héritera de SQLiteOpenHelper et qui devra implémenter 2 méthodes :

  • onCreate() qui est appelée à la toute première création de la base de données.
  • onUpgrade() qui est appelée lors de l’upgrade de la base.

Nous allons alors définir cette classe :

package com.yoannzimero.sqlite.example;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class MySQLiteDatabase extends SQLiteOpenHelper {

	private static final String TABLE_CONTACTS = "table_contacts";
	private static final String COL_ID = "ID";
	private static final String COL_NOM = "NOM";
	private static final String COL_PRENOM = "PRENOM";
	private static final String COL_NUM_TEL = "NUM_TEL";

	private static final String CREATE_TABLE_CONTACTS = "CREATE TABLE "
			+ TABLE_CONTACTS + " (" + COL_ID
			+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + COL_NOM
			+ " TEXT NOT NULL, " + COL_PRENOM + " TEXT NOT NULL, "
			+ COL_NUM_TEL + " TEXT NOT NULL);";

	public MySQLiteDatabase(Context context, String name, CursorFactory factory,
			int version) {
		super(context, name, factory, version);
	}

	/**
	 * Cette méthode est appelée lors de la toute première création de la base
	 * de données. Ici, on doit créer les tables et éventuellement les populer.
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		// on crée la table table_contacts dans la BDD
		db.execSQL(CREATE_TABLE_CONTACTS);
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// on supprime la table table_contacts de la BDD et on recrée la BDD
		db.execSQL("DROP TABLE " + TABLE_CONTACTS + ";");
		onCreate(db);
	}

}

Manipulations de la base de données

Nous allons maintenant créer une classe qui va nous permettre de manipuler les données de la base de données.

Ainsi, nous pourrons ajouter de nouveaux contacts dans la base de données, les modifier, les consulter et enfin les supprimer. C’est le principe de CRUD (Create, Read, Update, Delete).

package com.yoannzimero.sqlite.example;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class ContactsBDD {

	private static final int VERSION_BDD = 1;
	private static final String NOM_BDD = "contacts.db";

	private static final String TABLE_CONTACTS = "table_contacts";
	private static final String COL_ID = "ID";
	private static final int NUM_COL_ID = 0;
	private static final String COL_NOM = "NOM";
	private static final int NUM_COL_NOM = 1;
	private static final String COL_PRENOM = "PRENOM";
	private static final int NUM_COL_PRENOM = 2;
	private static final String COL_NUM_TEL = "NUM_TEL";
	private static final int NUM_COL_NUM_TEL = 3;
	private SQLiteDatabase bdd;

	private MySQLiteDatabase maBaseSQLite;

	public ContactsBDD(Context context) {
		maBaseSQLite = new MySQLiteDatabase(context, NOM_BDD, null, VERSION_BDD);
	}

	/**
	 * Ouvre la BDD en écriture
	 */
	public void open() {
		bdd = maBaseSQLite.getWritableDatabase();
	}

	/**
	 * Ferme l'accès à la BDD
	 */
	public void close() {
		bdd.close();
	}

	public SQLiteDatabase getBDD() {
		return bdd;
	}

	/**
	 * Insère un contact en base de données
	 *
	 * @param contact
	 *            le contact à insérer
	 * @return l'identifiant de la ligne insérée
	 */
	public long insertContact(Contact contact) {
		ContentValues values = new ContentValues();

		// On insère les valeurs dans le ContentValues : on n'ajoute pas
		// l'identifiant car il est créé automatiquement
		values.put(COL_NOM, contact.getNom());
		values.put(COL_PRENOM, contact.getPrenom());
		values.put(COL_NUM_TEL, contact.getNumeroTelephone());

		return bdd.insert(TABLE_CONTACTS, null, values);
	}

	/**
	 * Met à jour le contact en base de données
	 *
	 * @param id
	 *            l'identifiant du contact à modifier
	 * @param contact
	 *            le nouveau contact à associer à l'identifiant
	 * @return le nombre de lignes modifiées
	 */
	public int updateContact(int id, Contact contact) {
		ContentValues values = new ContentValues();
		values.put(COL_NOM, contact.getNom());
		values.put(COL_PRENOM, contact.getPrenom());
		values.put(COL_NUM_TEL, contact.getNumeroTelephone());
		return bdd.update(TABLE_CONTACTS, values, COL_ID + " = " + id, null);
	}

	/**
	 * Supprime un contact de la BDD (celui dont l'identifiant est passé en
	 * paramètres)
	 *
	 * @param id
	 *            l'identifiant du contact à supprimer
	 * @return le nombre de contacts supprimés
	 */
	public int removeContactWithID(int id) {
		return bdd.delete(TABLE_CONTACTS, COL_ID + " = " + id, null);
	}

	/**
	 * Retourne le premier contact dont le numéro de téléphone correspond à
	 * celui en paramètre
	 *
	 * @param numeroTelephone
	 *            le numéro de téléphone
	 * @return le contact récupéré depuis la base de données
	 */
	public Contact getFirstContactWithNumeroTelephone(String numeroTelephone) {
		Cursor c = bdd.query(TABLE_CONTACTS, new String[] { COL_ID, COL_NOM,
				COL_PRENOM, COL_NUM_TEL }, COL_NUM_TEL + " LIKE ""
				+ numeroTelephone + """, null, null, null, null);
		return cursorToContact(c);
	}

	/**
	 * Convertit le cursor en contact
	 *
	 * @param c
	 *            le cursor à convertir
	 * @return le Contact créé à partir du Cursor
	 */
	private Contact cursorToContact(Cursor c) {
		// si aucun élément n'a été retourné dans la requête, on renvoie null
		if (c.getCount() == 0)
			return null;

		// Sinon on se place sur le premier élément
		c.moveToFirst();

		Contact contact = new Contact();
		contact.setId(c.getInt(NUM_COL_ID));
		contact.setNom(c.getString(NUM_COL_NOM));
		contact.setPrenom(c.getString(NUM_COL_PRENOM));
		contact.setNumeroTelephone(c.getString(NUM_COL_NUM_TEL));

		c.close();

		return contact;
	}
}

Tester notre application

Pour tester notre application, nous complèterons l’Activity que nous avons mise de côté pour l’instant.

Nous suivrons alors les étapes suivantes :

  • Insérer un nouveau contact en base de données
  • Récupérer le contact précédemment inséré
  • Modifier et mettre à jour en base de données le contact précédemment récupéré
  • Récupérer à nouveau le contact et constater que la valeur a bien été modifiée

Voici alors le code de notre activity :

package com.yoannzimero.sqlite.example;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

public class SQLiteExampleActivity extends Activity {
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		ContactsBDD contactBdd = new ContactsBDD(this);

		// On ouvre la base de données pour écrire dedans
		contactBdd.open();

		// Création et insertion d'un contact
		Contact contact = new Contact("Zimero", "Yoann", "066045");
		contactBdd.insertContact(contact);

		// Récupération du contact
		Contact contactFromBdd = contactBdd
				.getFirstContactWithNumeroTelephone("066045");
		// Si le contact à bien été ajouté à la BDD, on affiche les données du
		// contact dans un Toast et on modifie son numéro de téléphone dans la
		// BDD
		if (contactFromBdd != null) {
			Toast.makeText(this, contactFromBdd.toString(), Toast.LENGTH_LONG)
					.show();
			contactFromBdd.setNumeroTelephone("075609");
			contactBdd.updateContact(contactFromBdd.getId(), contactFromBdd);
		}

		// Récupération du contact grâce au nouveau numéro de téléphone
		contactFromBdd = contactBdd
				.getFirstContactWithNumeroTelephone("075609");
		// S'il existe un contact possédant ce numéro dans la BDD, alors on
		// affiche ses données dans un Toast et on le supprime de la base de
		// données
		if (contactFromBdd != null) {
			Toast.makeText(this, contactFromBdd.toString(), Toast.LENGTH_LONG)
					.show();
			contactBdd.removeContactWithID(contactFromBdd.getId());
		}

		contactBdd.close();
	}
}

Si vous souhaitez télécharger les sources de ce projet, cliquez ici.

Vous pourrez directement tester votre application sur l’émulateur ou depuis votre téléphone en suivant la procédure décrite dans l’article précédent : Lancer une application Android