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
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.

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.

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 enEntitys kunnen beide@ColumnInfogebruiken, waarmee u de kolominformatie kunt aanpassen die aan een veld is gekoppeld. - Ze kunnen beide
@Embeddedgebruiken, 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 eenDatabaseView. - Je definieert al je views in je apps met
views, maar je definieert entiteiten metentities.
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:
- Je haalt de e-mail op uit
editEmailen wijst deze toe aan een variabele:email. - Deze voorwaarde controle roept
validateEmail(email)aan, die controleert of de e-mailnullis of niet. Het retourneertfalseals hetnullis. Het controleert ook of de ingevoerde e-mail geldig is en retourneertfalseals dat niet het geval is. - De code in het
ifstatement wordt uitgevoerd wanneervalidateEmail(email)trueretourneert.mealbevat het type maaltijd dat de gebruiker uit de keuzegroepen heeft gekozen. - Als u eenmaal de waarde van
mealhebt, maakt uSurveyListItem.CustomerSurvey, dat alle informatie over de enquête bevat. Het trekt de waarden voorquestionOneAnswer,questionTwoAnswerenquestionThreeAnsweruittoggleButtonListeners(), die luisteraars voor dat doel heeft. - Hier slaat u
customerSurveyop doorinsertCustomerSurvey(customerSurvey)inCustomerSurveyViewModelaan te roepen, die de logica om op te slaan in Room afhandelt. - 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.

Geweldig, u hebt de enquête voltooid.

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 uitCustomerSurvey.
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
HappyBreakFastViewzoals u in een normale query zou doen. - U roept deze methode in
CustomerSurveyRepoop 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 lijstLiveDatavan het typeSurveyListItem.HappyBreakFastViewis, 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
happyBreakfastCustomersaangeroepen en de waarde ervan geobserveerd. - Binnen de observeer lambda wordt gecontroleerd of customerSurveyList
nullis of niet. Als de lijstnullis, stelt uTextView’s Geen enquêtes gevonden! bericht in op zichtbaar en verbergt uRecyclerView. Alsnullnietnullis, stelt u de zichtbaarheid vanTextViewin op GONE en toont uRecyclerView. U roept ookinitView(customerSurveyList)aan met decustomerSurveyListwaarde uitCustomerSurveyViewModel. -
initView(customerSurveySurveyList: List)initialiseertCustomerSurveysAdaptermetcustomerSurveyListen stelt de adapter voorRecyclerViewin opCustomerSurveysAdapter, 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.


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
Leave a Reply