Vistas de la base de datos con Room para Android
Room es una capa de abstracción sobre SQLite que Google empaquetó como una biblioteca de AndroidX y también recomienda. Desde la versión 2.1, Room ofrece la posibilidad de añadir Vistas de Base de Datos, también conocidas como consultas almacenadas.
Algunas de las buenas razones para utilizar Vistas de Base de Datos serían:
- Le facilitan la escritura de consultas complejas y su uso en consultas de Objetos de Acceso a Datos (DAO).
- Puedes consultar sólo los campos que necesitas, en lugar de tener que recorrer todos los campos de una tabla.
En este tutorial, construirás una aplicación de Encuestas a Clientes que permite a los clientes de un restaurante dejar sus comentarios, y luego guarda esos comentarios en la base de datos administrada por Room. Durante el proceso aprenderás lo siguiente:
- ¿Qué es una Vista de Base de Datos?
- ¿Cómo crear Vistas de Base de Datos?
- Cómo usarlas para simplificar la escritura de consultas SELECT
Este tutorial también utiliza Coroutines con Room. Para saber más, lea nuestro tutorial Coroutines With Room Persistence Library.
Cómo empezar
Descargue el proyecto de inicio haciendo clic en el botón Download Materials en la parte superior o inferior de este tutorial.
Extraiga el archivo ZIP y abra el proyecto de inicio en Android Studio 4.0 o posterior seleccionando Open an existing Android Studio project en la pantalla de bienvenida.
Una vez completada la sincronización con Gradle, explora la estructura del proyecto. El proyecto sigue la arquitectura MVVM, por lo que las funcionalidades similares están bajo un mismo paquete. Familiarízate con los paquetes presentes – los usarás en este tutorial.
Construye y ejecuta. Verá una pantalla sencilla con un mensaje de bienvenida, una imagen y un botón START SURVEY.
Toque el botón de INICIO DE ENCUESTA. Para el propósito de este tutorial, puede ignorar el hecho de que no ha comido en el restaurante. :]
La siguiente pantalla es la de la encuesta. Tiene un campo de entrada de correo electrónico, botones de radio para elegir la comida que está calificando y tres preguntas. Cada pregunta tiene botones de «bueno», «medio» y «malo» debajo, para que el usuario pueda calificar su satisfacción.
También verás el botón SUBMIT SURVEY. Tócalo y verás un brindis que dice que aún no es hora de hacer la encuesta. No te preocupes, lo solucionarás a lo largo de este tutorial.
Ahora te han dado la bienvenida al restaurante The View, donde podrás ver increíbles vistas de la naturaleza, probar sus deliciosos platos y valorar tu satisfacción. Mientras que en él, usted también aprenderá acerca de las vistas de la base de datos de habitaciones.
Usando las vistas de la base de datos
Considera una tabla que tiene una funcionalidad extra de consultas SELECT pre-empacadas para la conveniencia. La versión 2.1 y superior de Room las denomina Vista de base de datos y proporciona una anotación con el mismo nombre, es decir, @DatabaseView
.
Usando esta anotación puedes marcar una clase para que se comporte como una Vista de Base de Datos. Esto le permitirá adjuntar una consulta a la clase, como a continuación:
@DatabaseView("SELECT user.id, user.name " + "AS departmentName FROM user " + "WHERE user.departmentId = department.id")class User { var id: Long = 0 var name: String? = null}
A continuación, puede utilizar esta clase en su DAO para consultar los datos de la misma manera que lo haría con una clase marcada como una Entidad, es decir, Tabla en una base de datos.
Un DAO le ayuda a acceder a los datos de la base de datos de su aplicación. Normalmente contiene los métodos CUD (Create, Update y Delete) y también puede contener otros métodos que pueden ser necesarios para el acceso de lectura y escritura a la base de datos.
La relación entre las Vistas de Base de Datos y la base de datos es similar a la relación entre las entidades y la base de datos. A continuación se profundizará en esas relaciones.
Comparación de una Vista de Base de Datos y una Entidad
Las clases anotadas con @DatabaseView
son similares a las clases Entity
. He aquí cómo:
- Ambos pueden utilizar SELECT FROM en las consultas DAO.
-
Database View
s yEntity
s pueden ambos utilizar@ColumnInfo
, que permite personalizar la información de la columna asociada a un campo. - Ambos pueden utilizar
@Embedded
, que permite que un campo tenga campos anidados que las consultas pueden referenciar directamente.
Aunque hay muchas similitudes entre los dos, también hay diferencias entre DatabaseView
s y Entity
s:
- Se puede utilizar INSERT, UPDATE y DELETE con un
Entity
, pero no con unDatabaseView
. - Defines todas tus vistas en tus apps usando
views
, pero defines las entidades usandoentities
.
Ahora que sabes qué es un DatabaseView
y cómo se compara y contrasta con una clase Entity
, es el momento de usarlo y empezar a presentar la encuesta para El Restaurante de Vistas.
Enviar la encuesta
Tu primer paso es añadir la lógica para enviar la encuesta y guardarla en la base de datos de Room después de tocar el botón SUBMIT SURVEY.
Navega hasta customersurveys/CustomerSurveyFragment.kt, donde añadirás la lógica para recoger las respuestas y guardarlas en Room. Hazlo reemplazando el código en submitSurvey()
con esto:
// 1val email = editEmail.text.toString()// 2if (validateEmail(email)) { // 3 val meal = when (radioGroupMeals.checkedRadioButtonId) { R.id.radioBreakfast -> "Breakfast" R.id.radioLunch -> "Lunch" R.id.radioDinner -> "Dinner" else -> "No Meal" } // 4 val customerSurvey = SurveyListItem .CustomerSurvey(0, email, meal, questionOneAnswer, questionTwoAnswer, questionThreeAnswer) customerSurveyViewModel.insertCustomerSurvey(customerSurvey) // 5 findNavController() .navigate(R.id.action_surveyFragment_to_surveyCompletedFragment)}
Esto es lo que estás haciendo con este código:
- Obtienes el correo electrónico de
editEmail
y lo asignas a una variable:email
. - Esta comprobación de la condición llama a
validateEmail(email)
, que comprueba si el correo electrónico esnull
o no. Devuelvefalse
si esnull
. También comprueba si el correo electrónico introducido es válido y devuelvefalse
si no lo es. - El código dentro de la sentencia
if
se ejecuta cuandovalidateEmail(email)
devuelvetrue
.meal
mantiene el tipo de comida que el usuario seleccionó de los grupos de radio. - Una vez que tiene el valor de
meal
, creaSurveyListItem.CustomerSurvey
, que tiene toda la información sobre la encuesta. Saca los valores dequestionOneAnswer
,questionTwoAnswer
yquestionThreeAnswer
detoggleButtonListeners()
, que tiene listeners para ello. - Aquí se guarda
customerSurvey
llamando ainsertCustomerSurvey(customerSurvey)
enCustomerSurveyViewModel
, que maneja la lógica para guardar en Room. - Se navega a SurveyCompletedFragment.
Después de añadir esto, notará que customerSurveyViewModel
y findNavController()
tienen subrayados en rojo. Para arreglar esto, primero añada la inicialización CustomerSurveyViewModel
en la parte superior de la clase, justo debajo de la inicialización questionThreeAnswer
.
private val customerSurveyViewModel: CustomerSurveyViewModel by viewModels()
Asegúrese de añadir las respectivas declaraciones de importación cuando el IDE le pida.
Construya y ejecute. Inicie la encuesta, introduzca el correo electrónico requerido y seleccione sus respuestas a las preguntas.
Grandioso, ha completado la encuesta.
Toque el botón VER ENCUESTAS… oops, no hace nada todavía. No te preocupes, lo arreglarás pronto.
En la siguiente sección, aprenderás a crear tu primera DatabaseView
.
Crear una vista de base de datos
Para crear una vista, añadirás una anotación @DatabaseView
a una clase o clase de datos. Comience por navegar a customersurveys/SurveyListItem.kt. Esta es una clase sellada con un par de clases de datos para que usted utilice en este tutorial.
En la parte inferior de SurveyListItem
, justo debajo de QuestionOneSadView
, agregue lo siguiente:
data class HappyBreakFastView( override val email: String) : SurveyListItem()
Esta clase de datos anula la variable de correo electrónico de SurveyListItem
y hereda de la clase – lo que significa que es un subtipo de SurveyListItem
.
Después de crear esta clase de datos, añada @DatabaseView
con una consulta SELECT para obtener todos los identificadores de correo electrónico de la tabla CustomerSurvey donde la comida se establece como «Desayuno», justo encima de la clase de datos HappyBreakFastView
. Su anotación debería tener el siguiente aspecto:
@DatabaseView("SELECT CustomerSurvey.email FROM CustomerSurvey WHERE CustomerSurvey.meal = 'Breakfast'")
Algunas cosas a tener en cuenta sobre la consulta dentro de la anotación:
- La consulta funciona como cualquier otra consulta que haya escrito en Room.
- Necesita solicitar todos los campos que tenga en su clase de datos mientras escribe la consulta. En este caso, sólo necesitas el correo electrónico. Utiliza
SELECT CustomerSurvey.email From...
para obtener el correo electrónico deCustomerSurvey
.
¡Felicidades, has creado tu primera vista! A continuación, vas a ver cómo puedes utilizar la vista en tus consultas DAO.
Utilización de las vistas de la base de datos de la sala en las consultas DAO
Primero, incluirás HappyBreakFastView
en views
en el @Database
de la app.
Navega hasta database/AppDatabase.kt y, dentro de views
, añade SurveyListItem.HappyBreakFastView::class
. Su anotación @Database
actualizada debería tener el siguiente aspecto:
@Database(entities = , version = 2, exportSchema = false, views = )
Nota que el version = 2
. Debe actualizar la versión de la base de datos cada vez que añada un view
en la AppDatabase – de lo contrario, su aplicación se bloqueará. En este caso, has actualizado la versión a 2. Sincroniza gradle para aplicar todos estos cambios.
A continuación, navega hasta customers/CustomerSurveysDao.kt y, justo debajo de getQuestionOneSadView()
, añade el siguiente código:
@Query("SELECT * FROM HappyBreakFastView")fun getHappyBreakFastCustomers():LiveData<List<SurveyListItem.HappyBreakFastView>>
Este método obtiene todos los clientes que estaban contentos con cualquier aspecto de la encuesta del restaurante. Para explicarlo con más detalle:
- Primero, se utiliza
HappyBreakFastView
como se haría en una consulta normal. - Se llama a este método en
CustomerSurveyRepo
para obtener una lista de todos los clientes que respondieron a alguna de las preguntas con Bien. Observa que el tipo de retorno del método es una listaLiveData
de tipoSurveyListItem.HappyBreakFastView
, que es un soporte de variable observable.
Ahora, has creado un view
y el método para consultar la lista de clientes que respondieron con una respuesta positiva en CustomerSurveysDao
. En la siguiente sección, usted aprenderá cómo llamar a este método de la clase de repositorio.
La obtención de datos utilizando un DatabaseView
Navegue a customersurveys/CustomerSurveyRepo.kt y añadir el siguiente método justo debajo de getQuestionOneSadView()
:
fun getHappyBreakFastCustomers() : LiveData<List<SurveyListItem.HappyBreakFastView>> { return customerSurveysDao.getHappyBreakFastCustomers()}
Este método llama getHappyBreakFastCustomers()
de CustomerSurveysDao
para obtener los datos de la Sala. Su tipo de retorno es un LiveData
, lo que permite al que llama a este método observar cualquier cambio en los datos.
A continuación, se añade una llamada a getHappyBreakFastCustomers()
en CustomerSurveyViewModel
. Es responsable de mostrar los datos a la vista – que, en este caso, no es DatabaseView
sino AllSurveysFragment.
Navega hasta customersurveys/CustomerSurveyViewModel.kt y añade el siguiente código:
val happyBreakfastCustomers : LiveData<List<SurveyListItem.HappyBreakFastView>> by lazy { customerSurveyRepo.getHappyBreakFastCustomers()}
Esta variable obtiene su valor llamando a getHappyBreakFastCustomers()
desde CustomerSurveyRepo
. Hay un by lazy{}
para que no cargue los datos inmediatamente, sino cuando se accede a la variable por primera vez.
A continuación, actualizará la UI para que pueda mostrar los datos.
Mostrar los datos a la UI
Navegue a allsurveys/AllSurveysFragment.kt y añade el siguiente código en la parte inferior de la clase:
private fun getHappyBreakfastCustomers() { customerSurveyViewModel.happyBreakfastCustomers.observe(viewLifecycleOwner, Observer { customerSurveyList -> if (customerSurveyList.isEmpty()) { layoutEmptyView.visibility = View.VISIBLE rvReviews.visibility = View.GONE } else { layoutEmptyView.visibility = View.GONE rvReviews.visibility = View.VISIBLE initView(customerSurveyList) } })}private fun initView(customerSurveySurveyList: List<SurveyListItem.HappyBreakFastView>) { val customerSurveysAdapter = CustomerSurveysAdapter(customerSurveySurveyList) rvReviews.adapter = customerSurveysAdapter}
Para explicar lo que hace el código:
- Primero, llama a
happyBreakfastCustomers
y observa su valor. - Dentro de la lambda observar, hay una comprobación para ver si customerSurveyList es
null
o no. Si la lista esnull
, se pone el mensaje deTextView
¡No se han encontrado encuestas! como visible y se ocultaRecyclerView
. Si no esnull
, pones la visibilidad deTextView
a GONE y muestrasRecyclerView
. También llamas ainitView(customerSurveyList)
con el valorcustomerSurveyList
deCustomerSurveyViewModel
. -
initView(customerSurveySurveyList: List)
InicializaCustomerSurveysAdapter
concustomerSurveyList
y establece el adaptador paraRecyclerView
aCustomerSurveysAdapter
, que ahora muestra la lista de encuestas a la UI.
El IDE te pedirá que añadas la importación de SurveyListItem
. Si no lo hace, añada esta importación:
import com.raywenderlich.android.customersurveys.customersurveys.SurveyListItem
Ahora que ha mostrado los datos a la UI, sólo tiene unos pocos pasos más para que todo funcione perfectamente.
A continuación, añadirás el código que se encarga de obtener los datos de Room dependiendo de la opción seleccionada en el desplegable de la interfaz de usuario, es decir, el widget Spinner.
Obtención de datos para las diferentes vistas
Añade el siguiente trozo de código justo debajo de onCreate
en AllSurveysFragment.kt::
private fun spinnerListener() { filterSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onNothingSelected(parent: AdapterView<*>?) {} override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { when (position) { 0 -> resetState() 1 -> getAllCustomerSurveys() 2 -> getHappyBreakfastCustomers() 3 -> getSadDinnerCustomers() 4 -> getAverageLunchCustomers() 5 -> getQuestionOneSadCustomers() } } }}
El trozo de código anterior establece onItemSelectedListener
en filterSpinner
y anula dos métodos: onNothingSelected
y onItemSelected
. No quieres hacer nada cuando no hay nada seleccionado, así que onNothingSelected
se deja vacío. Sí se quiere reaccionar cuando se selecciona un elemento, por lo que hay que implementar onItemSelected
.
onItemSelected
tiene una expresión when
que llama a diferentes métodos dependiendo de la opción seleccionada en filterSpinner
. Estos métodos son similares a getHappyBreakfastCustomers()
, pero obtienen los datos utilizando un DatabaseView
diferente.
Asegúrate de añadir las importaciones cuando el IDE te lo pida.
Por último, añade una llamada a spinnerListener()
dentro de onViewCreated
, justo después de setupSpinner()
, como se muestra a continuación:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setupSpinner() // Added spinnerListener()}
Ahora que tienes todo listo para obtener las encuestas, tu siguiente paso es añadir el código para navegar a AllSurveysFragment
.
Navegar a Todas las Encuestas
Este es el último paso que necesitas para ver las vistas en acción.
Navega a completedsurvey/SurveyCompletedFragment.kt y descomenta el código dentro de btnViewSurveys
. Su resultado final se verá así:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) btnViewSurveys.setOnClickListener { findNavController() .navigate(R.id.action_surveyCompletedFragment_to_allSurveysFragment) }}
Aquí, simplemente está estableciendo el oyente de clic para el botón VIEW SURVEYS y navegando a AllSurveysFragment
.
Una vez que descomente el código, el IDE le pedirá que importe findNavController()
. Simplemente importe lo requerido.
Construya, ejecute e inicie una encuesta, luego conteste las preguntas y envíelas. Por último, visualiza Todas las encuestas, donde podrás obtener todos los datos en función de la opción que hayas seleccionado en el spinner.
¡Felicidades! Has terminado tu experiencia en el restaurante The View. Esperemos que hayas tenido una gran comida, hayas visto vistas increíbles y hayas tenido la oportunidad de aprender lo que son las DatabaseViews.
¿A dónde ir desde aquí?
Descarga el proyecto final utilizando el botón de descarga de materiales en la parte superior o inferior del tutorial.
Para obtener más información sobre las características de Room, consulta la documentación oficial de Android.
Esperamos que hayas disfrutado de este tutorial de Room Database Views. Si usted tiene alguna pregunta, comentarios o modificaciones impresionantes a este proyecto de aplicación, por favor únase a la discusión del foro a continuación.
raywenderlich.com Weekly
El boletín raywenderlich.com es la forma más fácil de mantenerse al día sobre todo lo que necesita saber como desarrollador móvil.
Obtenga un resumen semanal de nuestros tutoriales y cursos, y reciba un curso gratuito en profundidad por correo electrónico como bonificación
Valoración media
4.8/5
Añadir una valoración para este contenido
Iniciar sesión para añadir una valoración
.
Leave a Reply