Análisis y Diseño de Software
Departamento de Ingeniería de Sistemas Telemáticoshttp://moodle.dit.upm.es
Tema 4.5.1Acceso a DatosBase de Datos
Carlos A. Iglesias <[email protected]>
Acceso a Datos 2
Teoría
Ejercicio práctico en el ordenador
Ampliación de conocimientos
Lectura / Vídeo / Podcast
Práctica libre / Experimentación
Leyenda
Acceso a Datos 3
Temario
● 4.1 Introducción a Android [Gar10, cap1-2 ]
● 4.2 Desarrollo con Android [Gar10, cap3-5]
● 4.3 Interfaces de Usuario [Gar10, cap6]
● 4.4 Intenciones y Servicios [Gar10, cap7-8]
● 4.5 Acceso a Datos [Gar10, cap9]
– 4.5.1 Base de datos [Gar10, cap9]
Acceso a Datos 4
Bibliografía
● Libro de texto: – [Gar10] Learning Android, Marko Gargenta,
O'Reilly, 2010, Cap 9-10. Disponible en http://ofps.oreilly.com/titles/9781449390501/
● Android Developers– http://developer.android.com/reference/android/app/Service.html
– http://developer.android.com/resources/tutorials/testing/helloandroid_test.html
– http://developer.android.com/guide/topics/testing/testing_android.html
– http://developer.android.com/resources/tutorials/testing/activity_test.html
Acceso a Datos 5
Objetivos
● Aprender a utilizar almacenamiento persistente
● Recordar bases de datos y SQL
● Aprender a crear tablas, y consultar, insertar y borrar datos en una tabla
● Aprender a mostrar datos en una lista en una actividad
Acceso a Datos 6
Motivación
● En el tema anterior teníamos un servicio que podía listar mensajes.
● Queremos guardar los mensajes en una base de datos en el terminal para poder mostrar algo incluso aunque no haya conexión
Acceso a Datos 7
Base de Datos
● Ya vimos en FTEL– Que las Bases de Datos permitían guardar
datos de forma persistente– Que con SQL podíamos realizar diversas
operaciones, como consultar (SELECT-FROM), modificar (UPDATE), borrar (DELETE) o insertar datos (INSERT)
Acceso a Datos 9
SQLite
● Utilizada internamente por Firefox y Thuderbird
● Usada en múltiples sistemas operativos para dispositivos móviles (Android, iOS, Blackberry OS)
● No tiene claves ajenas (FOREIGN KEYS)
Acceso a Datos 10
Repaso SQL – create table
create table tblLIBROS (libroID integer PRIMARY KEY autoincrement, titulo text, autor text, anno integer)
Tipos: text, varchar, integer, float, numeric, date, time, timestamp,
boolean, blob, etc.
http://sqlite.org/datatype3.html
Acceso a Datos 11
Repaso SQL - insertar
insert into tblLIBROS(autor, titulo, anno) VALUES ('autor1', 'libro1', 2001);insert into tblLIBROS(autor, titulo, anno) VALUES ('autor2', 'libro2', 2002);insert into tblLIBROS(autor, titulo, anno) VALUES ('autor1', 'libro3', 2001);insert into tblLIBROS(autor, titulo, anno) VALUES ('autor4', 'libro4', 2004);
Acceso a Datos 12
Consultar (select-from) / query (I)
● select [distinct] <campos> from <tablas> where <condicion>group by <campos> having <grupos>order by <campos> [ASC|DESC];
● Ej. listar todos los autores
● Ej. listar autor, titulo y año anterior a 2002
select distinct autor from tblLIBROS;
select * from tblLIBROS where anno <= 2002;
Acceso a Datos 13
Consultar (select-from) / query (II)
● Ej. listar autor, titulo y año anterior a 2002 ordenado por autor
● Ej. listar cuántos autores hay por año
select * from tblLIBROS where anno <= 2002 ordered by autor;
select anno, count(*) from tblLIBROS grouped by anno;
Acceso a Datos 14
En Android...
● Usamos la clase SQLiteDatabase
● Nos da dos interfaces:– Ejecutar SQL
• execSQL(String sql) → CREATE, INSERT, UPDATE, DELETE
• rawQuery(String sql, String [] args) → SELECT
– Orientada a objetos (veremos)• query(), delete(), insert(), update()
Acceso a Datos 15
Ejemplo
SQLiteDatabase db = SQLiteDatabase.openOrCreate(“ejemplo.libros”, MODE_PRIVATE, null);String sql = "create table tblLIBROS ("
+ "libroID integer PRIMARY KEY autoincrement, "+ "titulo text, "+ "autor text, "+ "anno integer"+ ");";
db.execSQL(sql);String sqlInsert = "insert into tblLIBROS (autor, titulo, anno) VALUES ('autor1', 'libro1', 2001); ";db.execSQL(sql);String sqlSelect = "select distinct autor from tblLIBROS;";Cursor c = db.rawQuery(sqlSelect, null);int autorIdCol = c.getColumnIndex("autor");while (c.moveToNext()) {
Log.d(c.getString(autorIdCol));}
Cursor
Acceso a Datos 16
Base de datos en /data/data
Acceso a Datos 17
Ejemplo SQL - EjemploBaseDatosActivity
Llama a onCreate() de
DBHelper
Acceso a Datos 18
Ejemplo SQL DBHelper (I)
Acceso a Datos 19
Ejemplo SQL DBHelper (II)
Acceso a Datos 20
Ejemplo SQL DBHelper (III)
int autorIdCol = c.getColumnIndex("autor");while (c.moveToNext()) {
Log.d(c.getString(autorIdCol));}
Acceso a Datos 21
Ejemplo SQL DBHelper (IV)
Acceso a Datos 22
Consultas parametrizadas
● Podemos usar sentencias SQL parametrizadas
● Ej.
String sql = “select * from tblLIBROS where anno >= ? and anno <= ?”;String [] args = {“2000”, “2004” };db.execSQL(sql, args);
Acceso a Datos 23
SQLiteDatabase - query()
query(String tabla, String [] columnas, String where, String [] whereArgs, String groupBy, String having, String orderBy);
select columnas from tablawhere seleccióngroup by columnas having condicionorder by columnas
String sql = “select nombre, apellidos, sueldo from Empleados “;sql += “where sueldo >= ? and sueldo <= ? ”;sql += “order by nombre, apellidos”;String [] args = {“1000”, “2000”};Cursor c = db.rawQuery(sql, args);
String [] cols = {“nombre”, “apellidos”, “sueldo”};String where = “sueldo >= ? and sueldo <= ?”;String [] whereArgs = {“1000”, “2000”};String order = “nombre, apellidos”;Cursor c = db.query(“Empleados”, cols, where, whereArgs, null, null, order);
Acceso a Datos 24
SQLiteDatabasedelete(),insert()
public int delete(String tabla, String where, String [] whereArgs);public long insert(String tabla, String nullColumnHack, ContentValues valores);
String sqlInsert = “insert into Empleados values( 'Pepe', 'Perez', '1000');db.execSQL(sqlInsert);
String sqlDelete = “delete from Empleados where nombre = 'Pepe'”;db.execSQL(sqlDelete);
db.delete(“Empleados”,”nombre = 'Pepe'” , null);
ContentValues valores = new ContentValues(); // Map<String, String>valores.put(“nombre”, “Pepe”);valores.put(“apellidos”, “Perez”);Valores.put(“sueldo”, “1000”);db.insert(“Empleados”, null, valores);
SQL no permite insertar una columna null. Si valores es null, debemos indicar al
menos el nombre de una columna que permite meter un valor NULL. No es válido
INSERT INTO tabla. Hacemos INSERT INTO tabla (col1) VALUES (null);
Acceso a Datos 25
SQLiteDatabase - update()
public int update(String tabla, ContentValues valores, String where, String [] whereArgs);
ContentValues valores = new ContentValues(); // Map<String,String>valores.put(“nombre”, “Jose”);
db.update(“Empleados”, valores, “nombre='Pepe'”, null);
String sqlUpdate = “update Empleados set nombre = 'Jose' where nombre = 'Pepe'”;db.execSQL(sqlUpdate);
Acceso a Datos 26
Borrar la BD... Settings → Applications
Acceso a Datos 27
Ejemplo Yamba
● Vamos a crear una BD para el timeline– La encapsulamos en una clase StatusData
Acceso a Datos 28
Patrón de Diseño DAO
● DAO (Data Access Object)
● Un DAO contiene una conexión a una base de datos y sus operaciones básicas, ocultando su implementación
● En nuestro caso, StatusData sigue el patrón DAO del valor Status de Twitter
Acceso a Datos 29
StatusData (I)
Acceso a Datos 30
StatusData (II)
Acceso a Datos 31
StatusData (III)
Acceso a Datos 32
StatusData (IV)
Acceso a Datos 33
YambaSingleton3 (I)
Acceso a Datos 34
YambaSingleton3 (II)
Acceso a Datos 35
YambaSingleton3 (III)
Acceso a Datos 36
YambaSingleton3 (IV)
Acceso a Datos 37
UpdaterService4 (I)
Acceso a Datos 38
UpdaterService4 (II)
Acceso a Datos 39
UpdaterService4 (III)
Acceso a Datos 40
StatusActivity7 (I) (sin cambios)
Acceso a Datos 41
StatusActivity7 (II)
Acceso a Datos 42
StatusActivity7 (III)
Acceso a Datos 43
StatusActivity7 (IV)
Acceso a Datos 44
Lanzamos servicio...
Acceso a Datos 45
Lo que llevamos hecho...
Acceso a Datos 46
Yamba
● Vamos a mostrar los mensajes, recuperándolos de la base de datos
● Hacemos dos versiones– Una simple, con una nueva actividad que
muestre los mensajes– Otra más avanzada usando Adaptadores
Acceso a Datos 47
Cambios en la aplicación
● Queremos que cuando empiece el usuario en vez de la pantalla de Status, empiece con la pantalla de Timeline
● Pero... queremos que en ambas actividades el usuario pueda acceder a las opciones
Acceso a Datos 48
BaseActivity
- MovemosonCreateOptionsMenu() y onOptionsItemSelected() de StatusActivity a BaseActivity- Aprovechamos y cambiamos los dos botones start/stop service por uno (toggleService) que conmute
Acceso a Datos 49
res/values/strings.xml
Acceso a Datos 50
res/values/menu/menu2.xml
Acceso a Datos 51
BaseActivity
● New->Java Class
Acceso a Datos 52
BaseActivity (I)
Acceso a Datos 53
BaseActivity (II)
Acceso a Datos 54
BaseActivity (III)
Acceso a Datos 55
StatusActivity8 (I)
Sin gestionar el menú (lo hereda), quitados
onCreateOptionsMenu y onOptionsItemSelected
Acceso a Datos 56
StatusActivity8 (II)
Acceso a Datos 57
StatusActivity8 (III)
Acceso a Datos 58
Layout res/layout/timeline_basic.xml
● New->Android XML file
Acceso a Datos 59
Layout timeline_basic.xml
Acceso a Datos 60
TimelineActivity1
● New->Java Class
Acceso a Datos 61
TimelineActivity1 (I)
Acceso a Datos 62
TimelineActivity1 (II)
Acceso a Datos 63
AndroidManifest.xml
Acceso a Datos 64
Ejecutamos... y menú
Acceso a Datos 65
Segunda iteración
● El widget ScrollView puede funcionar, pero si hubiera muchos registros, sería muy ineficiente
● Vamos a user ListView– Podríamos usar ListActivity como vimos con
los intents, pero extendemos BaseActivity y ListActivity es aconsejable cuando sólo hay un widget ListView en la actividad y usamos un array
Acceso a Datos 66
res/layout/timeline.xml
Acceso a Datos 67
res/layout/row.xml
Acceso a Datos 68
Adaptador
● Conectan una vista con una fuente de datos
Acceso a Datos 69
SimpleCursorAdaptor
● En Eclipse la clase SimpleCursorAdaptor nos permite adaptar una base de datos a una vista– Debemos describir un registro (fila, en
row.xml), los datos (el cursor) y la correspondencia entre datos y la vista
Acceso a Datos 70
TimelineActivity2 (I)
Acceso a Datos 71
TimelineActivity2 (II)
Acceso a Datos 72
Actualizamos...
● AndroidManifest a TimelineActivity2● BaseActivity a TimelineActivity2 en el
switch
Acceso a Datos 73
Ejecutamos...
Se ve mal timestamp, vamos a arreglarlo
Acceso a Datos 74
ViewBinder
● Es un pequeño detalle● Inyectamos lógica de negocio que
convierte una marca de tiempo (timestamp) en tiempo relativo
Acceso a Datos 75
TimelineActivity3 (I)
Acceso a Datos 76
TimelineActivity3 (II)
Acceso a Datos 77
TimelineActivity3 (III)
Acceso a Datos 78
Ejecutamos...
Acceso a Datos 79
Lo que llevamos hecho...
Acceso a Datos 80
Resumen
● En este tema hemos aprendido – Cómo almacenar, consultar, borrar, insertar y
actualizar bases de datos en Android– Cómo manejar cursores de bases de datos– Patrones de diseño como DAO o adaptador– Cómo extender una actividad con funcionalidad
común– Cómo mostrar datos en una vista con scroll o un
adaptador– Buenas prácticas como refactorización
Acceso a Datos 81
¿Preguntas?
Top Related