Vizualizări de baze de date cu Room pentru Android

Room este un strat de abstractizare peste SQLite pe care Google l-a împachetat ca o bibliotecă AndroidX și pe care îl recomandă. Începând cu versiunea 2.1, Room oferă posibilitatea de a adăuga Database Views, cunoscute și sub numele de interogări stocate.

Câteva dintre motivele bune pentru a utiliza Database Views ar fi:

  • Ele vă facilitează scrierea de interogări complexe și utilizarea lor în interogări DAO (Data Access Object).
  • Puteți interoga doar câmpurile de care aveți nevoie, mai degrabă decât să trebuiască să parcurgeți toate câmpurile dintr-un tabel.

În acest tutorial, veți construi o aplicație Customer Surveys care permite clienților unui restaurant să lase un feedback, apoi salvează acest feedback în baza de date gestionată de Room. Pe parcursul procesului veți învăța următoarele:

  • Ce este un Database View?
  • Cum să creați Database Views?
  • Cum să le folosiți pentru a simplifica scrierea interogărilor SELECT
Notă: Acest tutorial presupune că aveți experiență în dezvoltarea pentru Android în Kotlin și că ați mai lucrat cu Room. Dacă nu sunteți familiarizat cu Room, aruncați o privire la tutorialul nostru Data Persistence with Room.

Acest tutorial folosește, de asemenea, Coroutines cu Room. Pentru a afla mai multe, citiți tutorialul nostru Coroutines with Room Persistence Library.

Începem

Descărcați proiectul de pornire făcând clic pe butonul Download Materials din partea de sus sau de jos a acestui tutorial.

Extrageți fișierul ZIP și deschideți proiectul de pornire în Android Studio 4.0 sau mai târziu selectând Open an existing Android Studio project din ecranul de întâmpinare.

După ce sincronizarea Gradle este completă, explorați structura proiectului. Proiectul urmează arhitectura MVVM, astfel încât funcționalitățile similare se află sub un singur pachet. Familiarizați-vă cu pachetele prezente – le veți folosi în acest tutorial.

Build și rulați. Veți vedea un ecran simplu cu un mesaj de bun venit, o imagine și un buton START SURVEY.

Screenul Start Survey al aplicației Customer Surveys

Apăsați butonul START SURVEY. În scopul acestui tutorial, puteți ignora faptul că nu ați luat masa la restaurant. :]

Următorul ecran este ecranul de sondaj. Acesta are un câmp de introducere a e-mailului, butoane radio pentru a alege masa pe care o evaluați și trei întrebări. Fiecare întrebare are dedesubt butoanele Bun, Mediu și Rău, astfel încât utilizatorul își poate evalua gradul de satisfacție.

Screenul de sondaj al aplicației Customer Surveys cu întrebările și evaluările posibile

Vă veți vedea și butonul SUBMIT SURVEY. Atingeți-l și veți vedea un toast care spune că încă nu este timpul să răspundeți la sondaj. Nu vă faceți griji, veți remedia acest lucru pe parcursul acestui tutorial.

Acum ați fost întâmpinat la The View Restaurant, unde veți avea ocazia să vedeți priveliști uimitoare din natură, să gustați mâncărurile lor delicioase și să vă evaluați satisfacția. În acest timp, veți învăța, de asemenea, despre Room Database Views.

Utilizarea vizualizărilor bazei de date

Considerați un tabel care are o funcționalitate suplimentară de interogări SELECT preambalate pentru comoditate. Room versiunea 2.1 și versiunile ulterioare le numește acestea ca Database View și oferă o adnotare cu același nume, adică @DatabaseView.

Utilizând această adnotare puteți marca o clasă pentru a se comporta ca un Database View. Acest lucru vă va permite să atașați o interogare clasei, ca mai jos:

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

Puteți utiliza apoi această clasă în DAO pentru a interoga date în același mod în care ați face-o cu o clasă marcată ca o entitate, adică un tabel într-o bază de date.

Un DAO vă ajută să accesați date din baza de date a aplicației dumneavoastră. Acesta conține de obicei metodele CUD (Create, Update și Delete) și poate conține și alte metode care pot fi necesare pentru accesul de citire și scriere la baza de date.

Relația dintre Database Views și baza de date este similară cu relația dintre entități și baza de date. În continuare veți examina mai în profunzime aceste relații.

Compararea între o vizualizare a bazei de date și o entitate

Classele adnotate cu @DatabaseView sunt similare cu clasele Entity. Iată cum:

  • Ambele pot folosi SELECT FROM în interogările DAO.
  • Database Views și Entitys pot folosi ambele @ColumnInfo, care vă permite să personalizați informațiile de coloană asociate cu un câmp.
  • Ambele pot folosi @Embedded, care permite unui câmp să aibă câmpuri imbricate pe care interogările le pot referi direct.

În timp ce există multe asemănări între cele două, există și diferențe între DatabaseViews și Entitys:

  • Puteți folosi INSERT, UPDATE și DELETE cu un Entity, dar nu și cu un DatabaseView.
  • Îți definești toate vizualizările din aplicațiile tale folosind views, dar definești entitățile folosind entities.

Acum că știi ce este o DatabaseView și cum se compară și contrastează cu o clasă Entity, este timpul să o folosești și să începi să trimiți sondajul pentru The View Restaurant.

Submiterea sondajului

Primul dvs. pas este să adăugați logica pentru a trimite sondajul și a-l salva în baza de date Room după ce apăsați butonul SUBMIT SURVEY.

Navigați la customersurveys/CustomerSurveyFragment.kt, unde veți adăuga logica pentru colectarea răspunsurilor și salvarea lor în Room. Faceți acest lucru înlocuind codul din submitSurvey() cu acesta:

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

Iată ce faceți cu acest cod:

  1. Obțineți e-mailul din editEmail și îl atribuiți unei variabile: email.
  2. Această verificare de condiție apelează validateEmail(email), care verifică dacă e-mailul este null sau nu. Aceasta returnează false dacă este null. De asemenea, verifică dacă e-mailul introdus este valid și returnează false dacă nu este.
  3. Codul din interiorul instrucțiunii if se execută atunci când validateEmail(email) returnează true. meal reține tipul de masă pe care utilizatorul l-a selectat din grupurile radio.
  4. După ce aveți valoarea lui meal, creați SurveyListItem.CustomerSurvey, care are toate informațiile despre sondaj. Acesta extrage valorile pentru , questionTwoAnswer și questionThreeAnswer din toggleButtonListeners(), care are ascultători în acest scop.
  5. Aici, salvați customerSurvey prin apelarea lui insertCustomerSurvey(customerSurvey) în CustomerSurveyViewModel, care se ocupă de logica de salvare în Room.
  6. Navigați la SurveyCompletedFragment.

După ce ați adăugat acest lucru, veți observa că customerSurveyViewModel și findNavController() au sublinieri roșii. Pentru a remedia acest lucru, adăugați mai întâi inițializarea CustomerSurveyViewModel în partea de sus a clasei, chiar sub inițializarea questionThreeAnswer.

private val customerSurveyViewModel: CustomerSurveyViewModel by viewModels()

Asigurați-vă că adăugați declarațiile de import respective atunci când IDE vă solicită acest lucru.

Constituiți și rulați. Porniți sondajul, introduceți adresa de e-mail necesară și selectați răspunsurile la întrebări.

Screenul sondajului cu răspunsurile

Genial, ați finalizat sondajul.

Vizualizați toate sondajele folosind Vizualizări ale bazei de date Captură de ecran

Atingeți butonul Vizualizare sondaje… ups, nu face nimic încă. Nu vă faceți griji, veți rezolva asta în curând.

În următoarea secțiune, veți învăța cum să vă creați prima DatabaseView.

Crearea unei vizualizări a bazei de date

Pentru a crea o vizualizare, veți adăuga o adnotare @DatabaseView la o clasă sau la o clasă de date. Începeți prin a naviga la customersurveys/SurveyListItem.kt. Aceasta este o clasă sigilată cu câteva clase de date pe care le veți folosi în acest tutorial.

În partea de jos a SurveyListItem, chiar sub QuestionOneSadView, adăugați următoarele:

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

Această clasă de date suprascrie variabila email din SurveyListItem și moștenește din clasă – ceea ce înseamnă că este un subtip al SurveyListItem.

După crearea acestei clase de date, adăugați @DatabaseView cu o interogare SELECT pentru a prelua toate ID-urile de e-mail din tabelul CustomerSurvey în care masa este setată la „Breakfast”, chiar deasupra clasei de date HappyBreakFastView. Adnotarea dvs. ar trebui să arate astfel:

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

Câteva lucruri de reținut despre interogarea din interiorul adnotării:

  • Interogarea funcționează ca orice altă interogare pe care ați scris-o în Room.
  • Trebuie să solicitați toate câmpurile pe care le aveți în clasa dvs. de date pe măsură ce scrieți interogarea. În acest caz, aveți nevoie doar de e-mail. Folosiți SELECT CustomerSurvey.email From... pentru a obține e-mailul din CustomerSurvey.
Notă: Pentru acest tutorial, păstrați vizualizările și entitatea în interiorul SurveyListItem pentru a evita repetițiile și pentru a face codul mai ușor de citit. Nu trebuie întotdeauna să vă subclasați vederile într-o clasă sigilată; ele pot fi, de asemenea, în propriul fișier sau clasă separată.

Felicitări, ați creat prima vedere! În continuare, veți vedea cum puteți utiliza vizualizarea în interogările DAO.

Utilizarea vizualizărilor bazei de date a camerei în interogările DAO

În primul rând, veți include HappyBreakFastView în views în @Database aplicației.

Navigați în database/AppDatabase.kt și, în interiorul views, adăugați SurveyListItem.HappyBreakFastView::class. Adnotarea dvs. actualizată @Database ar trebui să arate ca mai jos:

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

Atenție, observați că version = 2. Trebuie să actualizați versiunea bazei de date de fiecare dată când adăugați un view în AppDatabase – în caz contrar, aplicația dvs. se va bloca. În acest caz, ați actualizat versiunea la 2. Sincronizați gradle pentru a aplica toate aceste modificări.

În continuare, navigați la customers/CustomerSurveysDao.kt și, chiar sub getQuestionOneSadView(), adăugați următorul cod:

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

Acestă metodă obține toți clienții care au fost mulțumiți de orice aspect al sondajului din restaurant. Pentru a o explica mai detaliat:

  • În primul rând, folosiți HappyBreakFastView așa cum ați face într-o interogare normală.
  • Apelează această metodă în CustomerSurveyRepo pentru a obține o listă cu toți clienții care au răspuns la oricare dintre întrebări cu Bine. Rețineți că tipul de retur al metodei este o listă LiveData de tip SurveyListItem.HappyBreakFastView, care este un deținător de variabile observabile.

Acum, ați creat un view și metoda de interogare a listei de clienți care au răspuns cu un răspuns pozitiv în CustomerSurveysDao. În secțiunea următoare, veți învăța cum să apelați această metodă din clasa repository.

Fetching Data Using a DatabaseView

Navigați în customersurveys/CustomerSurveyRepo.kt și adăugați următoarea metodă chiar sub getQuestionOneSadView():

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

Această metodă apelează getHappyBreakFastCustomers() din CustomerSurveysDao pentru a obține datele din Room. Tipul său de retur este un LiveData, ceea ce permite celui care apelează această metodă să observe orice modificare a datelor.

În continuare, veți adăuga un apel la getHappyBreakFastCustomers() în CustomerSurveyViewModel. Acesta este responsabil pentru afișarea datelor în vizualizare – care, în acest caz, nu este DatabaseView, ci AllSurveysFragment.

Navigați la customersurveys/CustomerSurveyViewModel.kt și adăugați următorul cod:

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

Această variabilă își obține valoarea prin apelarea lui getHappyBreakFastCustomers() din CustomerSurveyRepo. Există un by lazy{} astfel încât să nu încărcați datele imediat, ci mai degrabă atunci când variabila este accesată pentru prima dată.

În continuare, veți actualiza interfața de utilizator astfel încât aceasta să poată afișa datele.

Afișarea datelor în interfața de utilizator

Navigați la allsurveys/AllSurveysFragment.kt și adăugați următorul cod în partea de jos a clasei:

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}

Pentru a explica ce face codul:

  • În primul rând, îl apelează pe happyBreakfastCustomers și îi observă valoarea.
  • În interiorul lambdei observe, există o verificare pentru a vedea dacă customerSurveyList este null sau nu. Dacă lista este null, se setează mesajul TextView‘No surveys found! la vizibil și se ascunde RecyclerView. Dacă nu este null, se setează vizibilitatea lui TextView la GONE și se afișează RecyclerView. De asemenea, apelați initView(customerSurveyList) cu valoarea customerSurveyList din CustomerSurveyViewModel.
  • initView(customerSurveySurveyList: List) inițializează CustomerSurveysAdapter cu customerSurveyList și setează adaptorul pentru RecyclerView la CustomerSurveysAdapter, care acum afișează lista de sondaje la UI.

IDE vă va solicita să adăugați importul SurveyListItem. Dacă nu o face, adăugați acest import:

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

Acum că ați afișat datele la UI, mai aveți doar câțiva pași până când totul va funcționa perfect.

În continuare, veți adăuga codul care se ocupă de preluarea datelor din Room în funcție de opțiunea selectată pe lista derulantă din interfața cu utilizatorul, adică widgetul Spinner.

Fetching Data for the Different Views

Adaugați următoarea bucată de cod chiar sub onCreate în 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() } } }}

Piesa de cod de mai sus setează onItemSelectedListener la filterSpinner și suprascrie două metode: onNothingSelected și onItemSelected. Nu doriți să faceți nimic atunci când nu este selectat nimic, așa că onNothingSelected este lăsat gol. Doriți să reacționați la momentul în care este selectat un element, deci trebuie să implementați onItemSelected.

onItemSelected are o expresie when care apelează diferite metode în funcție de opțiunea selectată în filterSpinner. Aceste metode sunt similare cu getHappyBreakfastCustomers(), dar preiau datele folosind un DatabaseView diferit.

Asigurați-vă că adăugați importurile atunci când IDE vă solicită.

În cele din urmă, adăugați un apel la spinnerListener() în interiorul onViewCreated, imediat după setupSpinner(), așa cum se arată mai jos:

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

Acum că aveți totul pregătit pentru a prelua sondajele, următorul pas este să adăugați codul pentru a naviga la AllSurveysFragment.

Navigați la toate sondajele

Acesta este ultimul pas de care aveți nevoie pentru a vedea vizualizările în acțiune.

Navigați la completedsurvey/SurveyCompletedFragment.kt și decomentați codul din interiorul btnViewSurveys. Rezultatul final va arăta astfel:

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

Aici, pur și simplu setați ascultătorul de clic pentru butonul VIEW SURVEYS și navigați la AllSurveysFragment.

După ce decomentați codul, IDE vă va solicita să importați findNavController(). Pur și simplu importați cele necesare.

Constituiți, rulați și porniți un sondaj, apoi răspundeți la întrebări și trimiteți-le. În cele din urmă, vizualizați All Surveys (Toate sondajele), de unde veți putea prelua toate datele în funcție de opțiunea pe care ați selectat-o pe spinner.

Opțiuni de spinner în aplicație
Listă de clienți mulțumiți în medie folosind o vizualizare a bazei de date
Clienți cu cină tristă care nu au fost găsiți folosind o vizualizare a bazei de date

Felicitări! Ați finalizat experiența dumneavoastră la restaurantul The View. Sperăm că ați avut o masă minunată, ați văzut priveliști uimitoare și ați avut ocazia să învățați ce sunt DatabaseViews.

Unde să mergem de aici?

Descărcați proiectul final folosind butonul Download Materials din partea de sus sau de jos a tutorialului.

Pentru mai multe informații despre caracteristicile Room, consultați documentația oficială de la Android.

Sperăm că v-a plăcut acest tutorial Room Database Views. Dacă aveți întrebări, comentarii sau modificări grozave la acest proiect de aplicație, vă rugăm să vă alăturați discuției de pe forumul de mai jos.

raywenderlich.com Weekly

Buletinul raywenderlich.com este cel mai simplu mod de a fi la curent cu tot ceea ce trebuie să știți în calitate de dezvoltator mobil.

Obțineți un rezumat săptămânal al tutorialelor și cursurilor noastre și primiți ca bonus un curs gratuit de aprofundare prin e-mail!

Nota medie

4.8/5

Adaugați un rating pentru acest conținut

Autentificați-vă pentru a adăuga un rating

10 ratinguri

.

Leave a Reply