Database Views mit Room für Android
Room ist eine Abstraktionsschicht über SQLite, die Google als AndroidX-Bibliothek verpackt hat und auch empfiehlt. Seit Version 2.1 bietet Room die Möglichkeit, Database Views, auch bekannt als gespeicherte Abfragen, hinzuzufügen.
Einige der guten Gründe für die Verwendung von Database Views sind:
- Sie erleichtern das Schreiben komplexer Abfragen und deren Verwendung in Data Access Object (DAO)-Abfragen.
- Sie können nur die Felder abfragen, die Sie benötigen, und müssen nicht alle Felder in einer Tabelle durchgehen.
In diesem Lernprogramm werden Sie eine Kundenumfrage-App erstellen, mit der die Kunden eines Restaurants ihr Feedback abgeben können, und dieses Feedback dann in einer von Room verwalteten Datenbank speichern. Während des Prozesses lernen Sie Folgendes:
- Was ist eine Datenbankansicht?
- Wie erstellt man Datenbankansichten?
- Wie verwendet man sie, um das Schreiben von SELECT-Abfragen zu vereinfachen
Dieses Tutorial verwendet auch Coroutines mit Room. Um mehr zu erfahren, lesen Sie unser Tutorial Coroutines with Room Persistence Library.
Getting Started
Laden Sie das Starterprojekt herunter, indem Sie auf die Schaltfläche Download Materials am oberen oder unteren Rand dieses Tutorials klicken.
Extrahieren Sie die ZIP-Datei und öffnen Sie das Starterprojekt in Android Studio 4.0 oder höher, indem Sie auf dem Begrüßungsbildschirm die Option Open an existing Android Studio project wählen.
Nachdem die Gradle-Synchronisierung abgeschlossen ist, erkunden Sie die Projektstruktur. Das Projekt folgt der MVVM-Architektur, sodass ähnliche Funktionalitäten in einem Paket zusammengefasst sind. Machen Sie sich mit den vorhandenen Paketen vertraut – Sie werden sie in diesem Tutorial verwenden.
Build und starten. Sie werden einen einfachen Bildschirm mit einer Willkommensnachricht, einem Bild und einer Schaltfläche START SURVEY sehen.
Tippen Sie auf die Schaltfläche „UMFRAGE STARTEN“. Für die Zwecke dieses Tutorials können Sie die Tatsache ignorieren, dass Sie nicht im Restaurant gegessen haben. :]
Der nächste Bildschirm ist der Umfrage-Bildschirm. Er enthält ein E-Mail-Eingabefeld, Optionsfelder zur Auswahl des zu bewertenden Gerichts und drei Fragen. Unter jeder Frage befinden sich die Schaltflächen „Gut“, „Durchschnitt“ und „Schlecht“, so dass der Benutzer seine Zufriedenheit bewerten kann.
Sie sehen auch die Schaltfläche UMFRAGE SENDEN. Wenn Sie darauf tippen, erscheint ein Toast, der besagt, dass es noch nicht Zeit ist, die Umfrage durchzuführen. Keine Sorge, das wird im Laufe dieses Tutorials korrigiert.
Du bist jetzt im The View Restaurant willkommen, wo du eine atemberaubende Aussicht auf die Natur genießen, die köstlichen Gerichte probieren und deine Zufriedenheit bewerten kannst. Dabei werden Sie auch etwas über die Datenbankansichten von Room erfahren.
Verwendung von Datenbankansichten
Betrachten Sie eine Tabelle, die der Einfachheit halber zusätzliche Funktionen von vorgefertigten SELECT-Abfragen hat. Room Version 2.1 und höher bezeichnet diese als Database View und bietet eine Anmerkung mit dem gleichen Namen, z.B. @DatabaseView
.
Mit dieser Annotation können Sie eine Klasse so kennzeichnen, dass sie sich wie eine Datenbankansicht verhält. Dies ermöglicht es Ihnen, eine Abfrage an die Klasse anzuhängen, wie unten:
@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}
Sie können dann diese Klasse in Ihrem DAO verwenden, um Daten auf die gleiche Weise abzufragen, wie Sie es mit einer Klasse tun würden, die als Entität, d.h. als Tabelle in einer Datenbank, markiert ist.
Ein DAO hilft Ihnen, auf Daten aus der Datenbank Ihrer Anwendung zuzugreifen. Sie enthält typischerweise die CUD-Methoden (Create, Update und Delete) und kann auch andere Methoden enthalten, die für den Lese- und Schreibzugriff auf die Datenbank notwendig sind.
Die Beziehung zwischen Database Views und der Datenbank ist ähnlich wie die Beziehung zwischen Entities und der Datenbank. Wir werden uns diese Beziehungen im nächsten Schritt genauer ansehen.
Vergleich zwischen einer Datenbankansicht und einer Entität
Klassen, die mit @DatabaseView
annotiert sind, ähneln den Entity
-Klassen. Hier ist, wie:
- Beide können SELECT FROM in DAO-Abfragen verwenden.
-
Database View
s undEntity
s können beide@ColumnInfo
verwenden, was Ihnen erlaubt, die Spalteninformationen, die mit einem Feld verbunden sind, anzupassen. - Sie können beide
@Embedded
verwenden, was einem Feld erlaubt, verschachtelte Felder zu haben, auf die Abfragen direkt verweisen können.
Während es viele Ähnlichkeiten zwischen den beiden gibt, gibt es auch Unterschiede zwischen DatabaseView
s und Entity
s:
- Sie können INSERT, UPDATE und DELETE mit einem
Entity
verwenden, aber nicht mit einemDatabaseView
. - Sie definieren alle Ihre Ansichten in Ihren Anwendungen mit
views
, aber Sie definieren Entitäten mitentities
.
Nun, da Sie wissen, was eine DatabaseView
ist und wie sie sich von einer Entity
-Klasse unterscheidet, ist es an der Zeit, sie zu verwenden und die Umfrage für The View Restaurant zu starten.
Senden der Umfrage
Der erste Schritt besteht darin, die Logik zum Senden der Umfrage und zum Speichern in der Room-Datenbank hinzuzufügen, nachdem Sie auf die Schaltfläche SURVEY SENDEN getippt haben.
Navigieren Sie zu customersurveys/CustomerSurveyFragment.kt, wo Sie die Logik zum Erfassen der Beantwortungen und zum Speichern in Room hinzufügen werden. Ersetzen Sie dazu den Code in submitSurvey()
durch den folgenden:
// 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)}
Mit diesem Code gehen Sie folgendermaßen vor:
- Sie erhalten die E-Mail aus
editEmail
und weisen sie einer Variablen zu:email
. - Diese Bedingungsprüfung ruft
validateEmail(email)
auf, die prüft, ob die E-Mailnull
ist oder nicht. Sie gibtfalse
zurück, wenn sienull
ist. Außerdem wird geprüft, ob die eingegebene E-Mail gültig ist, und wenn nicht, wirdfalse
zurückgegeben. - Der Code innerhalb der Anweisung
if
wird ausgeführt, wennvalidateEmail(email)
true
zurückgibt.meal
enthält die Art der Mahlzeit, die der Benutzer aus den Optionsgruppen ausgewählt hat. - Wenn Sie den Wert von
meal
haben, erstellen SieSurveyListItem.CustomerSurvey
, der alle Informationen über die Umfrage enthält. Es zieht die Werte fürquestionOneAnswer
,questionTwoAnswer
undquestionThreeAnswer
austoggleButtonListeners()
, das zu diesem Zweck Hörer hat. - Hier speichern Sie
customerSurvey
, indem SieinsertCustomerSurvey(customerSurvey)
inCustomerSurveyViewModel
aufrufen, das die Logik zum Speichern in Room übernimmt. - Sie navigieren zu SurveyCompletedFragment.
Nach dem Hinzufügen dieses Elements werden Sie feststellen, dass customerSurveyViewModel
und findNavController()
rot unterstrichen sind. Um dies zu beheben, fügen Sie zunächst die CustomerSurveyViewModel
-Initialisierung am Anfang der Klasse hinzu, direkt unter der questionThreeAnswer
-Initialisierung.
private val customerSurveyViewModel: CustomerSurveyViewModel by viewModels()
Stellen Sie sicher, dass Sie die entsprechenden Import-Anweisungen hinzufügen, wenn die IDE Sie dazu auffordert.
Erstellen und ausführen. Starten Sie die Umfrage, geben Sie die erforderlichen E-Mail-Eingaben ein und wählen Sie Ihre Antworten auf die Fragen aus.
Gut, Sie haben die Umfrage abgeschlossen.
Tippen Sie auf die Schaltfläche UMFRAGEN ANSEHEN… ups, das macht noch nichts. Keine Sorge, das werden Sie bald beheben.
Im nächsten Abschnitt erfahren Sie, wie Sie Ihre erste DatabaseView
erstellen.
Erstellen einer Datenbankansicht
Um eine Ansicht zu erstellen, fügen Sie eine @DatabaseView
-Anmerkung zu einer Klasse oder Datenklasse hinzu. Beginnen Sie damit, zu customersurveys/SurveyListItem.kt zu navigieren. Dies ist eine versiegelte Klasse mit einigen Datenklassen, die Sie in diesem Tutorial verwenden können.
Fügen Sie am Ende von SurveyListItem
, direkt unter QuestionOneSadView
, Folgendes hinzu:
data class HappyBreakFastView( override val email: String) : SurveyListItem()
Diese Datenklasse überschreibt die E-Mail-Variable aus SurveyListItem
und erbt von der Klasse – das heißt, sie ist ein Subtyp von SurveyListItem
.
Nach dem Erstellen dieser Datenklasse fügen Sie @DatabaseView
mit einer SELECT-Abfrage hinzu, um alle E-Mail-IDs aus der Tabelle „CustomerSurvey“ abzurufen, in der „Mahlzeit“ auf „Frühstück“ eingestellt ist, direkt über der Datenklasse HappyBreakFastView
. Ihre Anmerkung sollte wie folgt aussehen:
@DatabaseView("SELECT CustomerSurvey.email FROM CustomerSurvey WHERE CustomerSurvey.meal = 'Breakfast'")
Ein paar Dinge zur Abfrage innerhalb der Anmerkung:
- Die Abfrage funktioniert wie jede andere Abfrage, die Sie in Room geschrieben haben.
- Sie müssen alle Felder abfragen, die Sie in Ihrer Datenklasse haben, wenn Sie die Abfrage schreiben. In diesem Fall brauchen Sie nur die E-Mail. Sie verwenden
SELECT CustomerSurvey.email From...
, um die E-Mail vonCustomerSurvey
.
Glückwunsch, Sie haben Ihre erste Ansicht erstellt! Als Nächstes werden Sie sehen, wie Sie die Ansicht in Ihren DAO-Abfragen verwenden können.
Verwendung von Raumdatenbankansichten in DAO-Abfragen
Zuerst werden Sie HappyBreakFastView
in views
in die @Database
der App einfügen.
Navigieren Sie zu database/AppDatabase.kt und fügen Sie innerhalb von views
SurveyListItem.HappyBreakFastView::class
hinzu. Ihre aktualisierte @Database
-Anmerkung sollte wie folgt aussehen:
@Database(entities = , version = 2, exportSchema = false, views = )
Beachten Sie, dass die version = 2
. Sie müssen die Datenbankversion jedes Mal aktualisieren, wenn Sie eine view
in der AppDatabase hinzufügen – andernfalls wird Ihre App abstürzen. In diesem Fall haben Sie die Version auf 2 aktualisiert. Synchronisieren Sie gradle, um alle diese Änderungen anzuwenden.
Nächste navigieren Sie zu customers/CustomerSurveysDao.kt und fügen Sie direkt unter getQuestionOneSadView()
den folgenden Code hinzu:
@Query("SELECT * FROM HappyBreakFastView")fun getHappyBreakFastCustomers():LiveData<List<SurveyListItem.HappyBreakFastView>>
Diese Methode holt alle Kunden, die mit irgendeinem Aspekt der Umfrage zufrieden waren, aus dem Restaurant. Um es genauer zu erklären:
- Zunächst verwenden Sie
HappyBreakFastView
wie in einer normalen Abfrage. - Sie rufen diese Methode in
CustomerSurveyRepo
auf, um eine Liste aller Kunden zu erhalten, die auf eine der Fragen mit Gut geantwortet haben. Beachten Sie, dass der Rückgabetyp der Methode eine ListeLiveData
vom TypSurveyListItem.HappyBreakFastView
ist, die ein beobachtbarer Variablenhalter ist.
Nun haben Sie eine view
und die Methode zur Abfrage der Liste der Kunden, die mit einer positiven Antwort geantwortet haben, in CustomerSurveysDao
erstellt. Im nächsten Abschnitt erfahren Sie, wie Sie diese Methode von der Repository-Klasse aus aufrufen können.
Daten mit einer DatabaseView abrufen
Navigieren Sie zu customersurveys/CustomerSurveyRepo.kt und fügen Sie die folgende Methode direkt unter getQuestionOneSadView()
ein:
fun getHappyBreakFastCustomers() : LiveData<List<SurveyListItem.HappyBreakFastView>> { return customerSurveysDao.getHappyBreakFastCustomers()}
Diese Methode ruft getHappyBreakFastCustomers()
von CustomerSurveysDao
aus auf, um die Daten von Room zu erhalten. Ihr Rückgabetyp ist LiveData
, was es dem Aufrufer dieser Methode ermöglicht, alle Änderungen in den Daten zu beobachten.
Als Nächstes fügst du einen Aufruf von getHappyBreakFastCustomers()
in CustomerSurveyViewModel
hinzu. Sie ist für die Anzeige der Daten in der Ansicht verantwortlich – die in diesem Fall nicht DatabaseView
, sondern AllSurveysFragment ist.
Navigieren Sie zu customersurveys/CustomerSurveyViewModel.kt und fügen Sie den folgenden Code hinzu:
val happyBreakfastCustomers : LiveData<List<SurveyListItem.HappyBreakFastView>> by lazy { customerSurveyRepo.getHappyBreakFastCustomers()}
Diese Variable erhält ihren Wert durch den Aufruf von getHappyBreakFastCustomers()
aus CustomerSurveyRepo
. Es gibt ein by lazy{}
, damit Sie die Daten nicht sofort laden, sondern erst, wenn auf die Variable zum ersten Mal zugegriffen wird.
Als Nächstes aktualisieren Sie die Benutzeroberfläche, damit sie die Daten anzeigen kann.
Anzeigen der Daten auf der Benutzeroberfläche
Navigieren Sie zu allsurveys/AllSurveysFragment.kt und fügen Sie den folgenden Code am unteren Ende der Klasse hinzu:
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}
Um zu erklären, was der Code tut:
- Zuerst ruft er
happyBreakfastCustomers
auf und beobachtet seinen Wert. - Innerhalb des Observe-Lambdas gibt es eine Prüfung, um zu sehen, ob customerSurveyList
null
ist oder nicht. Wenn die Listenull
ist, setzen Sie die Meldung „Keine Umfragen gefunden!“ vonTextView
auf sichtbar und blendenRecyclerView
aus. Wenn es nichtnull
ist, setzen Sie die Sichtbarkeit vonTextView
auf GONE und zeigenRecyclerView
an. Außerdem rufen SieinitView(customerSurveyList)
mit demcustomerSurveyList
-Wert ausCustomerSurveyViewModel
auf. -
initView(customerSurveySurveyList: List)
initialisiertCustomerSurveysAdapter
mitcustomerSurveyList
und setzt den Adapter fürRecyclerView
aufCustomerSurveysAdapter
, der nun die Liste der Umfragen auf der Benutzeroberfläche anzeigt.
Die IDE wird Sie auffordern, den SurveyListItem
-Import hinzuzufügen. Wenn dies nicht der Fall ist, fügen Sie diesen Import hinzu:
import com.raywenderlich.android.customersurveys.customersurveys.SurveyListItem
Nachdem Sie die Daten in der Benutzeroberfläche angezeigt haben, sind nur noch wenige Schritte erforderlich, bis alles perfekt funktioniert.
Als Nächstes fügen Sie den Code hinzu, der das Abrufen von Daten aus Room in Abhängigkeit von der im Dropdown-Menü der Benutzeroberfläche, d. h. dem Spinner-Widget, ausgewählten Option behandelt.
Daten für die verschiedenen Ansichten abrufen
Fügen Sie das folgende Codestück direkt unter 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() } } }}
Das obige Codestück setzt onItemSelectedListener
auf filterSpinner
und überschreibt zwei Methoden: onNothingSelected
und onItemSelected
. Sie wollen nichts tun, wenn nichts ausgewählt ist, also bleibt onNothingSelected
leer. Sie wollen aber darauf reagieren, wenn ein Element ausgewählt wird, also müssen Sie onItemSelected
implementieren.
onItemSelected
hat einen when
-Ausdruck, der je nach der in filterSpinner
ausgewählten Option verschiedene Methoden aufruft. Diese Methoden sind ähnlich wie getHappyBreakfastCustomers()
, aber sie rufen Daten mit einem anderen DatabaseView
ab.
Stellen Sie sicher, dass Sie die Importe hinzufügen, wenn die IDE Sie dazu auffordert.
Fügen Sie schließlich einen Aufruf von spinnerListener()
innerhalb von onViewCreated
, direkt nach setupSpinner()
, wie unten gezeigt, hinzu:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setupSpinner() // Added spinnerListener()}
Nun, da Sie alles zum Abrufen der Umfragen vorbereitet haben, besteht Ihr nächster Schritt darin, den Code zum Navigieren zu AllSurveysFragment
hinzuzufügen.
Navigieren zu allen Umfragen
Dies ist der letzte Schritt, den Sie benötigen, um die Ansichten in Aktion zu sehen.
Navigieren Sie zu completedsurvey/SurveyCompletedFragment.kt und entkommentieren Sie den Code in btnViewSurveys
. Ihr Endergebnis wird wie folgt aussehen:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) btnViewSurveys.setOnClickListener { findNavController() .navigate(R.id.action_surveyCompletedFragment_to_allSurveysFragment) }}
Hier setzen Sie einfach den Click-Listener für die Schaltfläche VIEW SURVEYS und navigieren zu AllSurveysFragment
.
Nachdem Sie den Code entkommentiert haben, werden Sie von der IDE aufgefordert, findNavController()
zu importieren. Importieren Sie einfach die erforderliche.
Erstellen Sie eine Umfrage, führen Sie sie aus und starten Sie sie, beantworten Sie dann die Fragen und senden Sie sie ab. Abschließend sehen Sie sich alle Umfragen an, wo Sie alle Daten abrufen können, die von der Option abhängen, die Sie auf dem Spinner ausgewählt haben.
Glückwunsch! Sie haben Ihr Erlebnis im The View Restaurant beendet. Hoffentlich hast du gut gegessen, eine tolle Aussicht gesehen und gelernt, was DatabaseViews sind.
Wo geht’s weiter?
Lade das fertige Projekt herunter, indem du die Schaltfläche „Materialien herunterladen“ oben oder unten im Tutorial verwendest.
Weitere Informationen über die Funktionen von Room findest du in der offiziellen Dokumentation von Android.
Wir hoffen, dass dir dieses Tutorial über Room Database Views gefallen hat. Wenn Sie Fragen, Kommentare oder tolle Modifikationen zu dieser Projekt-App haben, nehmen Sie bitte an der Forumsdiskussion unten teil.
raywenderlich.com Weekly
Der Newsletter von raywenderlich.com ist der einfachste Weg, um über alles, was Sie als Mobilentwickler wissen müssen, auf dem Laufenden zu bleiben.
Holen Sie sich eine wöchentliche Zusammenfassung unserer Tutorials und Kurse und erhalten Sie als Bonus einen kostenlosen vertiefenden E-Mail-Kurs!
Durchschnittsbewertung
4.8/5
Bewertung für diesen Inhalt hinzufügen
Anmelden, um eine Bewertung hinzuzufügen
Leave a Reply