1. Análisis y Diseño
de Software
Tema 4.5.1
Acceso a Datos
Base de Datos
Carlos A. Iglesias <cif@gsi.dit.upm.es>
Departamento de Ingeniería de Sistemas Telemáticos
http://moodle.dit.upm.es
2. Leyenda
Teoría
Ejercicio práctico en el ordenador
Ampliación de conocimientos
Lectura / Vídeo / Podcast
Práctica libre / Experimentación
Acceso a Datos 2
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 3
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 4
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 5
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 6
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 7
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 9
10. Repaso SQL – create table
create table tblLIBROS (libroID integer PRIMARY KEY autoincrement,
titulo text,
autor text,
anno integer)
Tipos: text, varchar, integer, float,
http://sqlite.org/datatype3.html numeric, date, time, timestamp,
boolean, blob, etc.
Acceso a Datos 10
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 11
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
select distinct autor from tblLIBROS;
● Ej. listar autor, titulo y año anterior a 2002
select * from tblLIBROS where anno <= 2002;
Acceso a Datos 12
13. Consultar (select-from) /
query (II)
● Ej. listar autor, titulo y año anterior a 2002
ordenado por autor
select * from tblLIBROS where anno <= 2002 ordered by autor;
● Ej. listar cuántos autores hay por año
select anno, count(*) from tblLIBROS grouped by anno;
Acceso a Datos 13
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 14
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));
}
Acceso a Datos Cursor 15
20. Ejemplo SQL DBHelper (III)
int autorIdCol = c.getColumnIndex("autor");
while (c.moveToNext()) {
Log.d(c.getString(autorIdCol));
}
Acceso a Datos 20
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 22
23. SQLiteDatabase - query()
query(String tabla, String [] columnas, select columnas from tabla
String where, String [] whereArgs, where selección
String groupBy, String having, group by columnas having condicion
String orderBy); order 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 23
24. SQLiteDatabase
delete(),insert()
public int delete(String tabla, String where, String [] whereArgs);
public long insert(String tabla, String nullColumnHack, ContentValues valores);
String sqlDelete = “delete from Empleados where nombre = 'Pepe'”;
db.execSQL(sqlDelete);
db.delete(“Empleados”,”nombre = 'Pepe'” , null);
String sqlInsert = “insert into Empleados values( 'Pepe', 'Perez', '1000');
db.execSQL(sqlInsert);
ContentValues valores = new ContentValues(); // Map<String, String>
valores.put(“nombre”, “Pepe”);
SQL no permite insertar una columna null.
valores.put(“apellidos”, “Perez”);
Si valores es null, debemos indicar al
Valores.put(“sueldo”, “1000”);
menos el nombre de una columna que
db.insert(“Empleados”, null, valores);
permite meter un valor NULL. No es válido
INSERT INTO tabla. Hacemos INSERT
Acceso a Datos 24
INTO tabla (col1) VALUES (null);
25. SQLiteDatabase - update()
public int update(String tabla, ContentValues valores, String where, String [] whereArgs);
String sqlUpdate = “update Empleados set nombre = 'Jose' where nombre = 'Pepe'”;
db.execSQL(sqlUpdate);
ContentValues valores = new ContentValues(); // Map<String,String>
valores.put(“nombre”, “Jose”);
db.update(“Empleados”, valores, “nombre='Pepe'”, null);
Acceso a Datos 25
27. Ejemplo Yamba
● Vamos a crear una BD para el timeline
– La encapsulamos en una clase StatusData
Acceso a Datos 27
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 28
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 46
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 47
48. BaseActivity
- Movemos
onCreateOptionsMenu() y
onOptionsItemSelected()
de StatusActivity a
BaseActivity
- Aprovechamos y
cambiamos los dos
botones start/stop service
por uno (toggleService)
que conmute
Acceso a Datos 48
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 65
68. Adaptador
● Conectan una vista con una fuente de
datos
Acceso a Datos 68
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 69
73. Ejecutamos...
Se ve mal timestamp,
vamos a arreglarlo
Acceso a Datos 73
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 74
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 80