Persistencia de datos en Android con Room

2
5927

Índice de contenidos

1. Introducción

Con este tutorial aprenderás a usar Room, una librería para manejar bases de datos SQLite en Android de una manera más segura. Además desarrollaremos un ejemplo utilizando Kotlin.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: MacBook Pro 17’ (2,66 GHz Intel Core i7, 8GB DDR3)
  • Sistema operativo: macOS Sierra 10.13.6
  • Entorno de desarrollo: Android Studio 3.3
  • Versión SDK mínima: 16

3. SQLite

3.1. SQLite

SQLite es un sistema de dominio público de gestión de bases de datos relacionales. La principal ventaja que presenta es que no funciona como un proceso independiente, sino que forma parte de la aplicación que lo utiliza. Por tanto, no necesita ser instalado independientemente, ejecutado o detenido, ni tiene fichero de configuración. Además sigue los principios ACID.

En Android es bastante útil, ya que permite la utilización de una base de datos local en el dispositivo que utilice nuestra aplicación de una manera relativamente ligera y sencilla.

3.2. Inconvenientes

SQLite es relativamente de bajo nivel, por lo que presenta ciertos riesgos. Su implementación requiere tiempo y esfuerzo, ya que se deben escribir las sentencias SQL de la base de datos. Por ello, si el modelo de datos sufre cambios, tendremos que modificar estas sentencias manualmente, con el riesgo que ello implica. Por si esto no fuera poco, estas sentencias no se comprueban durante la compilación, por lo que hay un importante riesgo de errores en tiempo de ejecución.

4. Room

4.1. Room

Room es una librería que abstrae el uso de SQLite al implementar una capa intermedia entre esta base de datos y el resto de la aplicación. De esta forma se evitan los problemas de SQLite sin perder las ventajas de su uso.

Room funciona con una arquitectura cuyas clases se marcan con anotaciones preestablecidas. Por otro lado, la mayoría de las consultas a la base de datos sí se comprueban en tiempo de compilación.

4.2. Arquitectura

Las partes de las que se compone Room son las siguientes:

  • Entity: son clases que definen las tablas de la base de datos y de las entidades a utilizar.
  • DAO: interfaces que definen los métodos utilizados para acceder a la base de datos.
  • RoomDatabase: sirve de acceso a la base de datos SQLite a través de los DAOs definidos.

 

Además, es recomendable utilizar una clase intermedia a la cual denominamos Repository cuya finalidad es administrar las diferentes fuentes de datos.

4.3. Anotaciones

Para que se detecten qué clases tendrán que ser tratadas por esta librería y para indicar ciertas configuraciones debemos utilizar anotaciones. Las principales son las siguientes:

  • @Database: para indicar que la clase será el Database. Además, dicha clase debería ser abstracta y heredar de RoomDatabase.
  • @Dao: se utiliza para las interfaces de los DAOs.
  • @Entity: indica que la clase es una entidad.
  • @PrimaryKey: indica que el atributo al que acompaña será la clave primaria de la tabla. También podemos establecer que se asigne automáticamente si la incluimos así: @PrimaryKey(autoGenerate = true)».
  • @ColumnInfo: sirve para personalizar la columna de la base de datos del atributo asociado. Podemos indicar, entre otras cosas, un nombre para la columna diferente al del atributo.
  • @Ignore: previene que el atributo se almacene como campo en la base de datos.
  • @Index: para indicar el índice de la entidad.
  • @ForeingKey: indica que el atributo es una clave foránea relacionada con la clave primaria de otra entidad.
  • @Embedded: para incluir una entidad dentro de otra.
  • @Insert: anotación para los métodos de los DAOs que inserten en la base de datos.
  • @Delete: anotación para los métodos de los DAOs que borren en la base de datos.
  • @Update: anotación para los métodos de los DAOs que actualicen una entidad en la base de datos.
  • @Query: anotación para un método del DAO que realice una consulta en la base de datos, la cual deberemos especificar.

5. Ejemplo de utilización de Room

Vamos a desarrollar un ejemplo para ver cómo utilizar Room. Para ello vamos a crear una agenda sencilla con contactos y su teléfono.

5.1. Incorporando Room a nuestro proyecto

Para seguir este tutorial, crea un nuevo proyecto de Android con una actividad vacía. Una vez tengamos nuestro proyecto, tenemos que añadir las dependencias de Room para usarlo.

Para ello, abrimos el fichero de propiedades de gradle y lo editamos. Este tutorial se desarrolla con Kotlin, por lo que tendremos que añadir la dependencia de kapt. Además, nuestro ejemplo seguirá la arquitectura MVVM por lo que vamos a añadir las dependencias para el ViewModel y LiveData, aunque no es necesario para utilizar Room. El resultado es el siguiente:

5.2. Creando la Entity

Nuestra base de datos tendrá una tabla para los contactos. Por tanto, tenemos que crear una clase de tipo Entity.

Como puedes ver, la entidad tiene cuatro atributos y, como ninguno tiene la etiqueta @Ignore, todos serán columnas de la tabla. La clave primaria se autogenerará y sólo el apellido permitirá valores nulos. Además, todos los nombres de las columnas están especificados con la anotación @ColumnInfo.

5.3. Creando el DAO

Como ya se ha indicado, el DAO será una interfaz que especifica los métodos con los que accederemos a la entidad en la base de datos. Aunque en nuestro caso sólo vamos a insertar y listar todos los elementos, también tienes las funciones para borrar y modificar. También hay que fijarse en que el método getOrderedAgenda() devuelve un objeto de tipo LiveData. Esto no es obligatorio, pudiendo devolver un Array o una Lista, pero como nuestro ejemplo seguirá una arquitectura MVVM vamos a hacerlo así.

5.4. La RoomDatabase

Nuestra database será abstracta y seguirá el patrón singleton para que sea compartida por cualquier objeto que la utilice. Definimos una función que devolverá el DAO que queremos y en el método getInstance ordenaremos a Room que inicialice la instancia de la database si es null y luego la devolveremos.

5.5. La clase Repository

Nuestro repositorio accederá a la base de datos para recuperar el DAO de los contactos y tendrá dos métodos, uno para insertar y otro para recuperar el LiveData. Además, implementaremos una clase privada para poder ejecutar la llamada de inserción en un hilo independiente, ya que no se permite realizarla en el hilo principal.

5.6. Accediendo a Room desde el resto de la app

Llegados a este punto, ya tenemos Room implementado, por lo que ahora vamos a desarrollar el resto de la aplicación para acceder a la base de datos y manipular su contenido. Para empezar, vamos a desarrollar el View Model, que instanciará la clase ContactsRepository para recuperar el LiveData e insertar contactos.

Para seguir, modificaremos el layout activity_main.xml que encontramos dentro de la carpeta res>layout, en el cual incluiremos tres campos de texto y un botón para añadir contactos. Por otro lado, tendremos un TextView para poder mostrar los contactos, aunque también podríamos hacerlo por ejemplo con un ListView. El contenido debe quedar así:

Por último, vamos con la clase MainActivity. Esta clase debe observar el LiveData del ViewModel para mostrar los cambios y añadir un listener al botón para añadir el contacto cuando se pulse.

Con esto hemos terminado el tutorial, por lo que podemos ejecutar nuestra aplicación y añadir nuevos contactos que se mostrarán debajo del botón.

 

¡Muchas gracias por haber leído hasta aquí!

6. Referencias

http://www.sqlitetutorial.net/what-is-sqlite//a>
https://developer.android.com/reference/androidx/room/Room
https://www.sqlite.org/index.html
https://developer.android.com/training/data-storage/room/

2 Comentarios

Dejar respuesta

Please enter your comment!
Please enter your name here