Room, otra forma de crear Bases de Datos en Android #AndroidMeetsKotlin
Francisco Manuel López Jurado Colaboraciones 23/03/2018
Google nos sigue proporcionando componentes para simplificar el desarrollo y no tengamos que acudir a librerías de terceros, en este caso hablaremos sobre Room. Se trata de una nueva librería dentro de Android Architecture Components, su objetivo es proveer de una capa de abstracción sobre SQLite. Es importante destacar que tiene la misma potencia que SQLite, por lo que no tendremos problemas de rendimiento si nuestra BD está bien diseñada.
Para este post, tomaremos una base de datos muy simple, se trata de la típica relación que tenemos todos los desarrolladores de movilidad. Normalmente tenemos asignado un dispositivo de desarrollo para nuestro día a día en el trabajo. Por ello, tendremos dos únicas entidades:
- Desarrollador, con las siguientes propiedades: id, nombre, apellido, fecha de nacimiento.
- Teléfono Desarrollo, con las propiedades: id, nombre.
En cuanto a las relaciones, sólo tenemos una:
- Un desarrollador puede tener N móviles y un móvil de desarrollo puede tener 1 dueño en ese momento.
Una vez hemos explicado todo el escenario, ¡nos ponemos manos a la obra!
Añadimos la dependencias
Tendremos que agregar las siguientes dependencias en nuestro fichero build.gradle:
¡Importante! Si nuestro proyecto está en Kotlin, necesitaremos kapt en lugar de annotationProcessor.
Anotaciones
Las principales anotaciones que se usan con Room son:
- @Ignore. Indica que un campo dentro de una entidad no será almacenada en la BD.
- @PrimaryKey. El campo que lleve dicha anotación se tomará como clave primaria de la tabla.
- @Entity. Convertirá a la clase que esté precedida de esta anotación en una entidad / tabla de la BD.
- @ColumnInfo. Por defecto los nombres de las variables indican los nombres de las columnas en la tabla. Pero podemos establecer un nombre específico a las columnas con esta anotación.
- @Index. Declara el índice en una entidad.
- @ForeignKey. Podemos almacenar la clave primaria de otra tabla y especificarle que dicho campo es una clave foránea en nuestra tabla.
- @Embedded. Se usa cuando queremos incluir una entidad dentro de otra.
- @Dao. Marca la clase como un objeto de acceso de datos (Data Access Object).
- @Query. Indica que un método será tratado como consultas a la BD.
- @Insert. El método se encargará de hacer una inserción en la BD.
- @Delete. El método será marcado como una acción de borrado en la BD.
- @Update. El método que lo lleve se utilizará para actualizar objetos en la BD.
- @Database. Establece como RoomDataBase a la clase que lleve esta anotación.
Al crear una entidad, se creará automáticamente su tabla en la BD asociada. Además, para cada campo de la entidad se creará automáticamente una columna.
También, se pueden establecer propiedades para cambiar ciertos aspectos de la creación automática que hacen las anotaciones. Por ejemplo:
- @PrimaryKey. Tiene la propiedad "autoGenerate" para especificar si la clave primaria será establecida o se autogenerará al insertarse nuevos elementos en la tabla.
- @ColumInfo. Tiene la propiedad "name" para especificar el nombre de la columna en la tabla.
- @Entity. Tiene la propiedad "tableName" entre otras para especificar el nombre de la tabla.
Ahora que ya conocemos las distintas anotaciones que nos podemos encontrar, vamos a crear nuestras entidades y DAOs.
Creación de las entidades
Desarrollador (Developer.kt)
Después de crear la clase, incluiremos la anotación @Entity para marcarla como una entidad de la BD. En cuanto a los campos:
- id (Long) y marcado como clave primaria.
- name (String)
- surname (String)
- birthDate (Long). Le daremos nombre a este campo con la anotación @ColumnInfo y su propiedad "name".
Teléfono Desarrollador (DevelopmentPhone.kt)
Marcaremos la clase como @Entity. Tendremos declarada la clave foránea de la tabla Developer con las siguientes propiedades:
- parentColumns. Especificamos el campo al que hace referencia la clave.
- childColumns. Hace referencia a la propiedad de la tabla actual.
- onDelete. Especificaremos el comportamiento en el caso de un borrado (en cascada, no hacer nada, etc).
En cuanto a los campos:
- id (String) y marcado como clave primaria.
- name (String)
- developerId (Long). Clave foránea de la tabla Developer.
Creación de los DAOs
Se trata de interfaces que reunirán los método de acceso de datos (inserción, eliminación, actualización, consultas, etc) para una entidad. Los métodos encargados de hacer consultas a la BD (con la anotación @Query) tendrán entre paréntesis la consulta que se quiera hacer como si de SQLite se tratase. Los DAOs que tenemos en este caso son:
DeveloperDao.kt
DevelopmentPhone.kt
Como podemos ver, el método findDevelopmentPhoneByDeveloperName hará uso de un inner join con el fin de relacionar la clave foránea de la tabla DevelopmentPhone con el id de la tabla Developer.
Creamos la BD
Ahora que ya tenemos nuestras entidades y DAOs, vamos a crear la BD. Para ello, seguimos los siguientes pasos:
- Creamos una clase llamada MyDatabase y la marcamos con la anotación @Database. Dicha clase extiende de RoomDatabase, será abstracta y tendrá dos métodos abstractos con la obtención de los dos DAOs creados anteriormente.
- Dentro de dicha anotación estableceremos:
- entities. Se trata de un array con las clases de las entidades en nuestra BD.
- version. Indica el número de la versión de la BD.
- Creamos un objeto companion para acceder a la base de datos en la clase MyApplication y la inicializamos. (Ahora no nos centraremos en la arquitectura, sólo la funcionalidad). Permitiremos que se hagan consultas en hilo principal con allowMainThreadQueries().
La clase MyDatabase quedaría tal que así:
Para ver si hemos implementado correctamente la BD, compilamos nuestro proyecto, si el proyecto compila sin problemas será un buen indicativo de que no tenemos problemas en la creación de la misma. Con el fin de ver si definitivamente podemos guardar datos, insertamos un desarrollador en la BD:
Después de esto, el desarrollador será insertado en la BD.
En resumen, se trata de una librería de fácil configuración y curva de aprendizaje muy liviana, es por esto por lo que se convierte en otra nueva posibilidad para simplificar el uso de BDs en Android. Espero que os haya gustado.