Database Views Met Room voor Android

Room is een abstractie laag over SQLite dat Google verpakt als een AndroidX bibliotheek en beveelt ook aan. Sinds versie 2.1, Room biedt de mogelijkheid om Database Views, ook bekend als opgeslagen queries toe te voegen.

Enkele van de goede redenen om Database Views te gebruiken zou zijn:

  • Ze maken het gemakkelijk voor u om complexe query’s te schrijven en ze te gebruiken in Data Access Object (DAO) query’s.
  • U kunt alleen de velden bevragen die u nodig hebt, in plaats van alle velden in een tabel te moeten doorlopen.

In deze zelfstudie bouw je een app voor klantenenquêtes waarmee klanten van een restaurant feedback kunnen achterlaten en die feedback vervolgens in de beheerde database van Room wordt opgeslagen. Tijdens het proces leer je het volgende:

  • Wat is een Database View?
  • Hoe maak je Database Views?
  • Hoe gebruik je ze om het schrijven van SELECT queries te vereenvoudigen
Opmerking: Deze tutorial gaat ervan uit dat je ervaring hebt met het ontwikkelen voor Android in Kotlin en dat je al eerder met Room hebt gewerkt. Als je niet bekend bent met Room, kijk dan eens naar onze Data Persistence met Room tutorial.

Deze tutorial maakt ook gebruik van Coroutines met Room. Om meer te leren, lees onze Coroutines met Room Persistence Library tutorial.

Getting Started

Download het starter project door te klikken op de Download Materials knop aan de boven- of onderkant van deze tutorial.

Uitpakken van het ZIP-bestand en open het starter project in Android Studio 4.0 of later door het selecteren van Open een bestaand Android Studio project in het welkomstscherm.

Als de Gradle synchronisatie is voltooid, onderzoekt u de project structuur. Het project volgt MVVM architectuur, dus soortgelijke functionaliteiten zijn onder één pakket. Maak uzelf vertrouwd met de aanwezige pakketten – u zult ze gebruiken in deze tutorial.

Build en voer uit. U ziet een eenvoudig scherm met een welkomstbericht, een afbeelding en een knop START SURVEY.

Scherm Enquête starten van de app Klantenenquêtes

Tik op de knop ENQUÊTE STARTEN. In het kader van deze handleiding kunt u negeren dat u nog niet in het restaurant hebt gegeten.

Het volgende scherm is het enquêtescherm. Het heeft een e-mail invoerveld, radiobuttons om de maaltijd te kiezen die u beoordeelt en drie vragen. Onder elke vraag staan knoppen voor goed, gemiddeld en slecht, zodat de gebruiker zijn tevredenheid kan beoordelen.

Enquêtescherm van de app met vragen en mogelijke beoordelingen

U ziet ook de knop SUBMIT SURVEY. Als u hierop tikt, ziet u een toost waarin staat dat het nog geen tijd is om de enquête in te vullen. Maak je geen zorgen, je zult dat in de loop van deze tutorial oplossen.

Je bent nu welkom in The View Restaurant, waar je een prachtig uitzicht op de natuur te zien krijgt, van hun heerlijke maaltijden kunt proeven en je tevredenheid kunt beoordelen. Terwijl u bezig bent, leert u ook over Room Database Views.

Gebruik Database Views

Bekijk een tabel met extra functionaliteit van voorverpakte SELECT-query’s voor het gemak. Room versie 2.1 en hoger noemt dit een Database View en geeft een annotatie met dezelfde naam, nl @DatabaseView.

Met behulp van deze annotatie kunt u een klasse markeren om zich te gedragen als een Database View. Dit zal u toelaten om een query hechten aan de klasse, zoals hieronder:

@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}

U kunt dan gebruik maken van deze klasse in uw DAO om gegevens op te vragen op dezelfde manier je zou doen met een klasse gemarkeerd als een Entiteit dwz tabel in een database.

Een DAO helpt u toegang tot gegevens uit de database van uw app. Het bevat meestal de CUD (Create, Update en Delete) methoden en kan ook andere methoden die nodig kunnen zijn voor lezen en schrijven toegang tot de database bevatten.

De relatie tussen Database Views en de database is vergelijkbaar met de relatie tussen entiteiten en de database. U zult een diepere blik werpen op die relaties.

Vergelijking van een Database View en een Entity

Klassen geannoteerd met @DatabaseView zijn vergelijkbaar met Entity klassen.

  • Beiden kunnen SELECT FROM in DAO queries gebruiken.
  • Database Views en Entitys kunnen beide @ColumnInfo gebruiken, waarmee u de kolominformatie kunt aanpassen die aan een veld is gekoppeld.
  • Ze kunnen beide @Embedded gebruiken, waarmee een veld geneste velden kan hebben waar queries direct naar kunnen verwijzen.

Terwijl er veel overeenkomsten zijn tussen de twee, zijn er ook verschillen tussen DatabaseViews en Entitys:

  • U kunt INSERT, UPDATE en DELETE gebruiken met een Entity, maar niet met een DatabaseView.
  • Je definieert al je views in je apps met views, maar je definieert entiteiten met entities.

Nu je weet wat een DatabaseView is en hoe het zich verhoudt tot en contrasteert met een Entity class, is het tijd om het te gebruiken en te beginnen met het indienen van de enquête voor The View Restaurant.

De enquête indienen

De eerste stap is het toevoegen van de logica voor het indienen van de enquête en het opslaan ervan in de database Room nadat u op de knop SUBMIT SURVEY hebt getikt.

Navig naar customersurveys/CustomerSurveyFragment.kt, waar u de logica toevoegt voor het verzamelen van de reacties en het opslaan ervan in Room. Doe dit door de code in submitSurvey() te vervangen door deze:

// 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)}

Dit is wat je doet met deze code:

  1. Je haalt de e-mail op uit editEmail en wijst deze toe aan een variabele: email.
  2. Deze voorwaarde controle roept validateEmail(email) aan, die controleert of de e-mail null is of niet. Het retourneert false als het null is. Het controleert ook of de ingevoerde e-mail geldig is en retourneert false als dat niet het geval is.
  3. De code in het if statement wordt uitgevoerd wanneer validateEmail(email) true retourneert. meal bevat het type maaltijd dat de gebruiker uit de keuzegroepen heeft gekozen.
  4. Als u eenmaal de waarde van meal hebt, maakt u SurveyListItem.CustomerSurvey, dat alle informatie over de enquête bevat. Het trekt de waarden voor questionOneAnswer, questionTwoAnswer en questionThreeAnswer uit toggleButtonListeners(), die luisteraars voor dat doel heeft.
  5. Hier slaat u customerSurvey op door insertCustomerSurvey(customerSurvey) in CustomerSurveyViewModel aan te roepen, die de logica om op te slaan in Room afhandelt.
  6. U navigeert naar SurveyCompletedFragment.

Nadat u dit hebt toegevoegd, zult u merken dat customerSurveyViewModel en findNavController() rode onderstrepingen hebben. Om dit te verhelpen, voegt u eerst de CustomerSurveyViewModel initialisatie toe bovenaan de klasse, net onder de questionThreeAnswer initialisatie.

private val customerSurveyViewModel: CustomerSurveyViewModel by viewModels()

Zorg ervoor dat u de respectievelijke import statements toevoegt wanneer de IDE u daarom vraagt.

Bouw en voer uit. Start de enquête, voer de vereiste e-mailinvoer in en selecteer uw antwoorden op de vragen.

Enquêtescherm met antwoorden

Geweldig, u hebt de enquête voltooid.

Bekijk alle enquêtes met behulp van Databaseviews Screenshot

Tik op de knop VIEW SURVEYS… oeps, het doet nog niets. Maak je geen zorgen, dat komt binnenkort in orde.

In de volgende sectie leer je hoe je je eerste DatabaseView maakt.

Een Database View maken

Om een view te maken, voeg je een @DatabaseView annotatie toe aan een class of data class. Begin met het navigeren naar customersurveys/SurveyListItem.kt. Dit is een verzegelde klasse met een paar gegevensklassen die u in deze tutorial kunt gebruiken.

Onderaan SurveyListItem, net onder QuestionOneSadView, voegt u het volgende toe:

data class HappyBreakFastView( override val email: String) : SurveyListItem()

Deze gegevensklasse overruled de e-mail variabele uit SurveyListItem en erft van de klasse – wat betekent dat het een subtype is van SurveyListItem.

Nadat u deze gegevensklasse hebt gemaakt, voegt u @DatabaseView toe met een SELECT-query om alle e-mail-id’s op te halen uit de tabel CustomerSurvey waarin maaltijd is ingesteld op “Ontbijt”, net boven de gegevensklasse HappyBreakFastView. Uw annotatie zou er als volgt uit moeten zien:

@DatabaseView("SELECT CustomerSurvey.email FROM CustomerSurvey WHERE CustomerSurvey.meal = 'Breakfast'")

Een paar dingen om op te merken over de query in de annotatie:

  • De query werkt als elke andere query die u in Room hebt geschreven.
  • U moet alle velden die u in uw dataklasse hebt opvragen terwijl u de query schrijft. In dit geval, heb je alleen de e-mail nodig. U gebruikt SELECT CustomerSurvey.email From... om het e-mailadres op te halen uit CustomerSurvey.
Opmerking: Voor deze tutorial houdt u de weergaven en de entiteit binnen SurveyListItem om herhaling te voorkomen en om de code leesbaarder te maken. Je hoeft je views niet altijd te subklassen in een sealed class; ze kunnen ook in hun eigen aparte bestand of class staan.

Gefeliciteerd, je hebt je eerste view gemaakt! Nu ga je zien hoe je de view in je DAO queries kunt gebruiken.

Ruimte Database Views gebruiken in DAO Queries

Eerst zul je HappyBreakFastView in views in de @Database van de app opnemen.

Navig naar database/AppDatabase.kt en voeg in views SurveyListItem.HappyBreakFastView::class toe. Uw bijgewerkte @Database annotatie zou er als volgt uit moeten zien:

@Database(entities = , version = 2, exportSchema = false, views = )

Merk op dat de version = 2. U moet de databaseversie bijwerken elke keer dat u een view toevoegt in de AppDatabase – anders zal uw app crashen. In dit geval hebt u de versie bijgewerkt naar 2. Synchroniseer gradle om al deze wijzigingen toe te passen.

Navolg, navigeer naar customers/CustomerSurveysDao.kt en, net onder getQuestionOneSadView(), voeg de volgende code toe:

@Query("SELECT * FROM HappyBreakFastView")fun getHappyBreakFastCustomers():LiveData<List<SurveyListItem.HappyBreakFastView>>

Deze methode haalt alle klanten op die tevreden waren met enig aspect van de enquête van het restaurant. Om het in meer detail uit te leggen:

  • Eerst gebruikt u HappyBreakFastView zoals u in een normale query zou doen.
  • U roept deze methode in CustomerSurveyRepo op om een lijst te krijgen van alle klanten die op een van de vragen met Goed hebben geantwoord. Merk op dat het terugkeertype van de methode een lijst LiveData van het type SurveyListItem.HappyBreakFastView is, dat een waarneembare variabelehouder is.

Nu hebt u een view gemaakt en de methode om de lijst van klanten die met een positief antwoord hebben geantwoord in CustomerSurveysDao op te vragen. In de volgende sectie leer je hoe je deze methode kunt aanroepen vanuit de repository class.

Gegevens ophalen met behulp van een DatabaseView

Navigeer naar customersurveys/CustomerSurveyRepo.kt en voeg de volgende methode toe net onder getQuestionOneSadView():

fun getHappyBreakFastCustomers() : LiveData<List<SurveyListItem.HappyBreakFastView>> { return customerSurveysDao.getHappyBreakFastCustomers()}

Deze methode roept getHappyBreakFastCustomers() van CustomerSurveysDao aan om de gegevens van Room op te halen. Het terugkeertype is een LiveData, waardoor de aanroeper van deze methode eventuele veranderingen in de gegevens kan waarnemen.

Naar aanleiding hiervan voegt u in CustomerSurveyViewModel een oproep aan getHappyBreakFastCustomers() toe. Deze methode is verantwoordelijk voor het weergeven van de gegevens in de view – die in dit geval niet DatabaseView is, maar AllSurveysFragment.

Navigeer naar customersurveys/CustomerSurveyViewModel.kt en voeg de volgende code toe:

val happyBreakfastCustomers : LiveData<List<SurveyListItem.HappyBreakFastView>> by lazy { customerSurveyRepo.getHappyBreakFastCustomers()}

Deze variabele krijgt zijn waarde door getHappyBreakFastCustomers() aan te roepen vanuit CustomerSurveyRepo. Er is een by lazy{} zodat u de gegevens niet onmiddellijk laadt, maar wanneer de variabele voor het eerst wordt benaderd.

Volgende, zult u de UI bijwerken zodat het de gegevens kan weergeven.

Weergave van de gegevens aan de UI

Navig naar allsurveys/AllSurveysFragment.kt en voeg de volgende code toe onderaan de class:

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}

Om uit te leggen wat de code doet:

  • Eerst wordt happyBreakfastCustomers aangeroepen en de waarde ervan geobserveerd.
  • Binnen de observeer lambda wordt gecontroleerd of customerSurveyList null is of niet. Als de lijst null is, stelt u TextView’s Geen enquêtes gevonden! bericht in op zichtbaar en verbergt u RecyclerView. Als null niet null is, stelt u de zichtbaarheid van TextView in op GONE en toont u RecyclerView. U roept ook initView(customerSurveyList) aan met de customerSurveyList waarde uit CustomerSurveyViewModel.
  • initView(customerSurveySurveyList: List) initialiseert CustomerSurveysAdapter met customerSurveyList en stelt de adapter voor RecyclerView in op CustomerSurveysAdapter, die nu de lijst met enquêtes weergeeft aan de UI.

De IDE zal u vragen om de SurveyListItem import toe te voegen. Als dat niet het geval is, voeg dan deze import toe:

import com.raywenderlich.android.customersurveys.customersurveys.SurveyListItem

Nu je de gegevens hebt weergegeven in de UI, hoef je nog maar een paar stappen te doorlopen voordat alles perfect werkt.

Volgende, voeg je de code die het ophalen van gegevens van Room afhankelijk van de geselecteerde optie op de dropdown in de gebruikersinterface, d.w.z. Spinner widget.

Gegevens ophalen voor de verschillende schermen

Voeg het volgende stukje code toe net onder onCreate in 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() } } }}

Het stukje code hierboven zet onItemSelectedListener op filterSpinner en overschrijft twee methodes: onNothingSelected en onItemSelected. Je wilt niets doen als er niets geselecteerd is, dus onNothingSelected wordt leeg gelaten. U wilt wel reageren wanneer een item is geselecteerd, dus u moet onItemSelected implementeren.

onItemSelected heeft een when expressie die verschillende methoden aanroept, afhankelijk van de optie die in filterSpinner is geselecteerd. Deze methoden zijn vergelijkbaar met getHappyBreakfastCustomers(), maar ze halen gegevens op met behulp van een andere DatabaseView.

Zorg ervoor dat u de import toevoegt wanneer de IDE u daarom vraagt.

Tot slot voegt u een oproep toe aan spinnerListener() binnen onViewCreated, direct na setupSpinner(), zoals hieronder wordt weergegeven:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setupSpinner() // Added spinnerListener()}

Nu u alles klaar hebt om de enquêtes op te halen, is uw volgende stap het toevoegen van de code om naar AllSurveysFragment te navigeren.

Navigeren naar alle enquêtes

Dit is de laatste stap die u nodig hebt om de weergaven in actie te zien.

Navigeer naar completedsurvey/SurveyCompletedFragment.kt en verwijder het commentaar uit de code in btnViewSurveys. Uw eindresultaat zal er zo uitzien:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) btnViewSurveys.setOnClickListener { findNavController() .navigate(R.id.action_surveyCompletedFragment_to_allSurveysFragment) }}

Hier stelt u eenvoudig de klik listener voor de VIEW SURVEYS knop in en navigeert u naar AllSurveysFragment.

Als u het commentaar uit de code haalt, zal de IDE u vragen om findNavController() te importeren. Importeer eenvoudig de vereiste.

Bouw, voer uit en start een enquête, beantwoord dan de vragen en dien ze in. Bekijk tot slot Alle enquêtes, waar u alle gegevens kunt ophalen afhankelijk van de optie die u op de spinner hebt geselecteerd.

Spinneropties in de app
Gemiddeld tevreden klantenlijst met behulp van een Databaseweergave
Slechte dinerklanten niet gevonden met behulp van een Databaseweergave

Gefeliciteerd! U bent klaar met uw bezoek aan The View Restaurant. Hopelijk heeft u heerlijk gegeten, geweldige uitzichten gezien en de kans gehad om te leren wat DatabaseViews zijn.

Waarheen vanaf hier?

Download het eindproject met behulp van de knop Download Materialen boven of onder aan de tutorial.

Voor meer informatie over de functies van Room, bekijk de officiële documentatie van Android.

We hopen dat u genoten heeft van deze Room Database Views tutorial. Als u vragen, opmerkingen of geweldige aanpassingen aan dit project app, neem dan deel aan de forumdiscussie hieronder.

raywenderlich.com Wekelijks

De raywenderlich.com nieuwsbrief is de makkelijkste manier om up-to-date te blijven over alles wat je moet weten als een mobiele ontwikkelaar.

Wekelijks ontvangt u een overzicht van onze tutorials en cursussen, en als bonus ontvangt u een gratis diepgaande e-mailcursus!

Gemiddelde waardering

4.8/5

Voeg een waardering voor deze inhoud toe

Meld u aan om een waardering toe te voegen

10 waarderingen

Leave a Reply