Jimmy Gilbert
Professeur au Cégep de Sainte-Foy et Cégep Édouard-Montpetit
Votre nouveau prof : Jimmy Gilbert
Études
Dans un MIO, écrivez-moi:
Vos études et /ou expériences préalables?
Quelle serait votre carrière de rêve
Vos passions?
Et vous? Quel est votre parcours de vie?
Il reste 5 semaines (de torture :P)
2 cours théoriques
Le reste du temps est pour le TP3
Présentation et remise des TP3 le 14 mai
Les 3 profs seront présents
Même règles que Ben et François
Retard:
Durant la théorie = attente à la pause
Introduction (en cours)
Théorie sur SQLite
Présentation du TP3
Temps de brainstorm en équipe TP3
Comprendre comment utiliser SQLite sous Android
Mettre en pratique l'utilisation de SQLite sous Android
Et si il n’y a plus de Wifi ?
Et si on est sur le réseau cellulaire ?
Peut être que notre application n'a pas besoin de stocker l'info sur un serveur...
Etc.!
Pourquoi utiliser une base de données sur le téléphone si on a un serveur web pour ça ?
ATTENTION!!!
SQL n’est pas un langage si standardisé que cela!
À ce jour, avez-vous déjà vécu des différences en utilisant du code SQL?
ATTENTION!!!
Créez un constructeur privé pour empêcher l’instanciation de cette classe!
Pourquoi?
public class MyTableDatabaseTable {
public static final String CREATE_TABLE_SQL =
"CREATE TABLE myTable (" +
"id INTEGER PRIMARY KEY AUTOINCREMENT," +
"someText TEXT," +
"someNumber INTEGER)";
public static final String DROP_TABLE_SQL =
"DROP TABLE myTable";
public static final String INSERT_SQL = "INSERT INTO myTable (someText, someNumber) VALUES(?, ?)";
public static final String SELECT_ALL_SQL = "SELECT id, someText, someNumber FROM task";
private MyTableDatabaseTable() {
//Private constructor to prevent instantiation
}
}
// J'aime le thème Monokai ;)Pourquoi faire des requêtes préparées?
Sinon, il risque d’y avoir « Injection SQL ». (C'est quoi?)
Les « trous » dans les requêtes SQL sont représentés par des « ? » sous SQLite.
C'est plus sécuritaire et plus rapide, car les requêtes préparées sont compilées qu’une seule fois.
La classe SQLiteDatabase sert à faire des requêtes à la base de données.
Vous ne pouvez pas l’instancier directement : vous devez passer par Android.
Entre en scène le SQLiteOpenHelper.
Le SQLiteOpenHelper s’occupe de créer la base de données et ses tables automatiquement pour vous dès la première utilisation de la base de données.
S’occupe de créer la BD et d’y fournir une connexion.
public class ApplicationDatabaseHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
public ApplicationDatabaseHelper(Context context, String databaseFileName) {
super(context, databaseFileName, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
//Faire ceci pour chaque table que vous avez
sqLiteDatabase.execSQL(MyTableDatabaseTable.CREATE_TABLE_SQL);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
//Faire ceci pour chaque table que vous avez
sqLiteDatabase.execSQL(MyTableDatabaseTable.DROP_TABLE_SQL);
onCreate(sqLiteDatabase);
}
}Dans « onCreate » dans vos activités, créez votre SQLiteOpenHelper et demandez-lui une SQLiteDatabase.
Si vous ne faites que lire la base de données, demandez un « readableDatabase ».
Sinon, demandez un « writableDatabase ».
ATTENTION!!!
N’oubliez pas d’appeler « close » sur votre SQLiteOpenHelper à « onDestroy » !!
Pourquoi?
private ApplicationDatabaseHelper applicationDatabaseHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
applicationDatabaseHelper =
new ApplicationDatabaseHelper(this, DATABASE_FILE_NAME);
SQLiteDatabase sqLiteDatabase =
applicationDatabaseHelper.getWritableDatabase();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (applicationDatabaseHelper != null) {
applicationDatabaseHelper.close();
}
}Sur votre SQLiteDatabase, utilisez la méthode « rawQuery » pour exécuter une requête SQL de n’importe quel type.
Le premier paramètre est la requête SQL à compiler et à exécuter.
Le second paramètre est un tableau de « String » contenant les valeurs des paramètres de la requête.
ATTENTION!!!
La façon montrée n’est pas celle montrée sur le site AndroidDeveloppers.
public List<MyObject> retrieveAll() {
Cursor cursor = null;
try {
cursor = sqLiteDatabase.rawQuery(MyObjectDatabaseTable.SELECT_ALL_SQL,
new String[]{});
List<MyObject> myObjects = new LinkedList<>();
while (cursor.moveToNext()) {
MyObject myObject = new MyObject();
myObject.setId(cursor.getInt(0));
myObject.setSomeText(cursor.getString(1));
myObject.setSomeNumber(cursor.getInt(2));
myObjects.add(MyObject);
}
return myObjects;
} finally {
if (cursor != null) {
cursor.close();
}
}
}L’envoi des paramètres pour les requêtes préparées se fait dans le tableau de « String » envoyé à la méthode « rawQuery ».
database.rawQuery(MyObjectDatabaseTable.SELECT_ALL_SQL, new String[]{});
public void create(MyObject myObject) {
Cursor cursor = null;
sqLiteDatabase.beginTransaction();
try {
cursor = sqLiteDatabase.rawQuery(MyTableDatabaseTable.INSERT_SQL, new String[]{
myObject.getSomeText(),
String.valueOf(myObject.getSomeNumber())
});
cursor.moveToLast(); //Nécessaire pour effectuer l'écriture
sqLiteDatabase.setTransactionSuccessful(); //Pour confirmer que l'écriture peut se faire
} finally {
if (cursor != null) {
cursor.close();
}
sqLiteDatabase.endTransaction();
}
}
ATTENTION!!!
Si vous ne faites pas « cursor.moveToLast() », l’écriture ne se fera jamais dans la base de données.
Pourquoi?
Aussi, il faut confirmer que la transaction s’est bien effectuée avec « setTransactionSucessful() ».
Qu'est-ce qu'une transaction en BD?
ATTENTION!!!
N’oubliez pas de mettre toutes vos requêtes en constantes!!
cursor = sqliteDatabase.rawQuery("SELECT last_insert_rowid()", new String[]{});
cursor.moveToNext();
myObject.setId(cursor.getLong(0));
By Jimmy Gilbert
Les bases de données mobiles