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 View
s enEntity
s 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 DatabaseView
s en Entity
s:
- 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
editEmail
en wijst deze toe aan een variabele:email
. - Deze voorwaarde controle roept
validateEmail(email)
aan, die controleert of de e-mailnull
is of niet. Het retourneertfalse
als hetnull
is. Het controleert ook of de ingevoerde e-mail geldig is en retourneertfalse
als dat niet het geval is. - De code in het
if
statement wordt uitgevoerd wanneervalidateEmail(email)
true
retourneert.meal
bevat het type maaltijd dat de gebruiker uit de keuzegroepen heeft gekozen. - Als u eenmaal de waarde van
meal
hebt, maakt uSurveyListItem.CustomerSurvey
, dat alle informatie over de enquête bevat. Het trekt de waarden voorquestionOneAnswer
,questionTwoAnswer
enquestionThreeAnswer
uittoggleButtonListeners()
, die luisteraars voor dat doel heeft. - Hier slaat u
customerSurvey
op doorinsertCustomerSurvey(customerSurvey)
inCustomerSurveyViewModel
aan 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
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 lijstLiveData
van het typeSurveyListItem.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 lijstnull
is, stelt uTextView
’s Geen enquêtes gevonden! bericht in op zichtbaar en verbergt uRecyclerView
. Alsnull
nietnull
is, stelt u de zichtbaarheid vanTextView
in op GONE en toont uRecyclerView
. U roept ookinitView(customerSurveyList)
aan met decustomerSurveyList
waarde uitCustomerSurveyViewModel
. -
initView(customerSurveySurveyList: List)
initialiseertCustomerSurveysAdapter
metcustomerSurveyList
en stelt de adapter voorRecyclerView
in 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