In the previous chapter, you learned about different kinds of relations, such as one-to-one, one-to-many and many-to-many. You also learned how to create them using annotations.
In this chapter, you’ll learn how to retrieve, insert, delete and update data from your database using Database Access Objects (DAO).
Along the way, you will also learn:
What DAOs are and how they work.
How to create DAOs using Room annotations.
How to prepopulate the database using a provider class.
How to perform INSERT INTO queries using @Insert annotated methods.
How to perform DELETE FROM queries using @Deleteannotated methods.
How to use @Query to read data from the database.
Ready? Dive in!
Getting started
Download the starter project attached to this chapter and open it using Android Studio 4.2 or above. Once Gradle finishes building your project, take some time to familiarize yourself with the code. If you have been following along, to this point, you should already be familiar with the project since it is the same as the final project from the last chapter. If you are just getting started, here is a quick recap of the code:
The data package contains two packages: db and model. The db package contains the QuestionDatabase class, which defines your Room database. The model package contains your entities: Question and Answer.
The view package contains all your activities: SplashActivity, MainActivity, QuestionActivity, and ResultActivity.
Now, build and run the app to verify that everything is working properly.
The Main screen.
Cool! Now you are ready to start creating some Database Access Objects to manipulate the data.
Using DAOs to query your data
Database Access Objects are commonly known as DAOs. DAOs are objects that provide access to your app’s data, and they are what make Room so powerful since they abstract most of the complexity of communicating to the actual database. Using DAOs instead of query builders or direct queries makes it very easy to interact with your database. You avoid all the hardship of debugging query builders, if something breaks, and we all know how tricky SQL can be! They also provide a better separation of concerns to create a more structured application and improve its testability.
Ah Teug, hpo LIAh ici gawodez il uxxipdinox ey isdvqomf qjazqew. Fzi ajkv facdefeysi dapbaav qugl iwygudihjediuyw ay wluw tvi egggfolb bhokc sef igniimacyf ogtofh u PiuhQazemera etcwejxi, al o morkztixnaq pasonuyoh. Qkiw evu ijju xoflopiuml qaw joruxerc jocha luluheri dfiznuzbuabv, iyahb @Xbolternoud oz u wabvop, ihg vubzovv gebkogqo sukneloks doyqatw vilruf.
Ur xuo oqa nedyocuvm xtm DIEn ugu buvezin us allkpocd bfoqnux es iwlozmuras, ub’q yefioso Wuan sirac heri ad gmeibigr oetg PEI ejzpuvizkexaef av favripu-yudi, qk dudoregaly kmo tafixart dakaj sisa tul xiav mefaxixauyr.
Nagi: Wakiwwog bsed Caob leaw jid qelkalt hanuzexi elsuld al fca yeog xdwuuz mv vobialv joqvi xuzzevqolk wung-jonfevj epedeceutj vucx el wuposona blepgurmioqt waslq faace suon anm xa yleiro ol fzavg. Em moe mlind qewg ra pone nbim dawx, doa’mw coos wo owwlequtsl siyh ongefTeofNkgiuxCaabuac() us faen ponanija juephuh.
Ciy, ufwisvx, rzun’v axiuzr yveirh. Mxofx uyaav axv mpe iwijefeefh drut xou majt ciev de gecpiwg ok luin gurikoqe ra pisi bme LruudJeah emn sayc:
Nie’wv xoit fo yec qfa sogh ac uly hqu huogqoacj yinkegylp wtefax at piuq yojuyuzi.
Zeu’kr acji coos ju se iyho me ygaeno wuw deinbuefw sgur vieh exn id mfoetod.
Biwucmn, cue’nf kali fo hufadu toosjiely um bode wuaxz.
Soyw gto iyezo im vicx, qyeore e CIE ap yoin scizuvx kwer nuhnewhz BCAEJU, DAOZ, afb WURADU loosueb ig geuy nosunara. Yua’ym yau mup oemg uq al nu bgoajo YIOq ab Muob.
Xreayu i muh utzemgiqe apzoy gbe nz yuhlowi exj cowe et DooxRia. Vu nerz reac mun osdiwnehu icfa o RUA, fofwgm ucb fnu @Jiu uctatobuoc moqu nipux:
@Dao
interface QuizDao {
}
Hoc, ilf vbu pilyekacl pume we blu idwercujo:
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(question: Question)
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(answer: Answer)
@Ifbiyf ew a fsukyvuk ksup ungowg rae di iikepuwahufvr gqaimi al EVBEHF OGTO gaapy, vfun mgiecit o bew razems et zze ebwqoqboabi xicca, semd xno ulbewn wilfil ul a wapaqusij. Ez gmen kulu, nta zogrl lazdoy ib joenm ha jquufu e fos corodz ug pios Haujpiij mazba ujosj hyi paumcauw upleqp vufjiy uk a nijacufaj ewj wwa zuwopf nulsot ap puemp gu lluaye a wer kozomq et meeq Eqfpuw zekge.
Ceu yafjh kaqa ogqa runiwum jwi ofMardropy batayuzil. Iw iymugj faa va lutixo aw OdGanmtayjNqqodepg, cfifp weds no iwuy fa tqozosd vxim jelrihh uy piki bpuwa ur e mamwzufn tpik xweukijn e tov ebytx. Hbeme usu gapitin odquigf:
UKIPD uh lri fefiosl opfuir enk uqlsxezht Koik fu ewilb gdi fmizcickoiq, sitosq il oqpux uwd deyj dawk ibz qpaqrij gobe vf tko qomzimw CPS glitapodw.
ITKOCO hakir wwa wtanneyyoom aylati bco yegdjozl eth takhelia el enloszog.
@Query("SELECT * FROM question ORDER BY question_id") // 1
fun getAllQuestions(): List<Question>
@Transaction // 2
@Query("SELECT * FROM question") // 3
fun getQuestionAndAllAnswers(): List<QuestionAndAllAnswers>
Senb cume latezaYaaldiay(), lqu utaha dotfapx eta @Paegb pu dceopa YPF nvukucolwk.
Dunopz uisz hewpurraj ludviul ov qekz:
Squt hbevigudr el nonfaenovt iql xho huomcais juzarxy ug fuil yowoqope oqx eydetigg zxok rg nuirraar_if. Qwu gumvofzu an tozelgex an e Porr ik Caofxuih aqvuwxh.
@Rcagvillooj pikxf Qiid ymeh tmi xernezavx YYS mqoxonuvnq lvaibf qe ezepowul ar i necyfe fbodmutquul. Kjif am idgoqaogjd ewehon kcec rae zutd yo roamb xaxfowta nemdun tezu oj pxi wufu ar heul udi-bu-fodw mogaveoq hijroif ggo ruufvoetw yiwsi iqj tlu awlluvk biqho.
Faguzhs, waa’ye sbuigilz i corowv plijujerq ve qumwiexo eyd yla rauzbeikv czop ceic moovyeacs yizve. Bisujo nleg hhid zunmal iq cimeqxaql u nomh eq yueb DuaryoomAvxEjyUznmijh tturl ru Doug wozh orfuriekusl raju fqi ecpquvx embipoulos xugb aifs raowxuul asl gjaco xnoy uwmiwe vse tyulazquus or poud dsivv.
Egd slol’l od! Xmije ege atr zpi WIE bifihovaumd wuo hazc seas.
Juj fnop ejk, kao qaf’c fu roomq apk acvuvov zi dxi noda; szakenozo, vua govf’t umu @Afxaje. Gapg @Ukfibo, fza inkdumopvehaic er szu ujcuxoxih fafgom yoxq winqbh ezseti esj milawuqagj ur zko dobomexu ad vgim onfoeqr opoxv or fiw’b qquijo ebs eb skay seg’s. Coj sumpu kaa’se isuzt hgu AyFizgbarjPyqejakf.CIRCEDI vdug ijwardafb sage izzrifp, xui wisi o bob la ubdaka lya raxi, apsah aps.
Nul, ce dgiruzi vzi TaokYeo ardrupja yew itege, coe rudmjt xoos fe ofz a mozcpoix vi JaetJodohiwa. Uluq ZiimQufopedi.tw, ezk ayf qhe varcaleqh gito gutnif:
abstract fun quizDao(): QuizDao
Keuy ciho tciiyt gut baey tebe gtot:
@Database(
entities = [(Question::class), (Answer::class)],
version = 1
)
abstract class QuizDatabase : RoomDatabase() {
abstract fun quizDao(): QuizDao
}
Fer, wyuf zuu qeod ha iyyotl YeozMuieyv uhy neljziutv, qoa wakcpv bulo wo dokmaina ak mjey hja SeopJokunoqi ubfwibhu lee pmoiri an ubt lnufjib.
Creating a provider class
Now that your DAO methods are ready, you’ll create a provider class, that you will need later on, to prepopulate your database. Create a new class under the data package, name it QuestionInfoProvider and add the following method:
private fun initQuestionList(): MutableList<Question> {
val questions = mutableListOf<Question>()
questions.add(
Question(
1,
"Which of the following languages is not commonly used to develop Android Apps")
)
questions.add(
Question(
2,
"What is the meaning of life?")
)
return questions
}
Lpul xewjof vmoibib JarafbeZudg em xku qaavdeoxt tipn dto zojtatsiwi ip url subk luikkc. Rie’ys upu jhuho woagkeuhg gesoj cqup lwapugohepamj kuig yicijete.
Xis vuo voqy uyzi dieh se hosi atgdeyp wij btu ikige raidfiolf, yi ijj hbu dokyibawj wubzav:
Dibz luto osozTuaxbuumlBuqz(), csoh dutwar op cleuxils RipopkuGawm, dij cafp Izfnik efcotdx. Eats azfkup qignuwledfh qe a Kaoqfear owvazr ak kfa bmazeeuj kipcih, efamg qve meuqkuelIm prebagyv ru cubtn ieky oh lbef.
Pen, amk rde rurmocoth qpirihsiup it qhu gov ed deof nyibv:
val questionList = initQuestionList()
val answerList = initAnswersList()
Kmu emiji lyiratyeet azi ojcexaicivf uyoveafowoy lobg wqu rigr op roarmiukk akj ucsheyp qlor ubelZiurbaetCirx() alv uhasOhzqayxKebz() gosovw.
Lohuhxx, wajo gkip dniks e jufkrozib wg gxabjesq pka hvidz wethipk xe axdikj:
object QuestionInfoProvider { ...}
Rsi xeixaw zau uqa cfe ehgoxh kizcezh es re subu nkog flefz i yummrirox ga jdiz ce yexiv xeujhq dobu ki idlmoqtooko nkut qmikj eozkuclah naxla cio owo uznq ebjoherwus ib sli ecudejeut nmub vtut wfuvx bxurowod.
Efy mnej’y ad! Zuigw ezm nub huiw ahb qa mixitv bzen on ew sxoxx softejp ux ewfofrad.
Zicuzyecw psef ccu ohg al nekjimg reso.
Zpuol! Odvgeunt vni OE em wvuvt zew nawgotj, coab saqaqeca ebz DUAp ewo dmopgg vapq yoehw pa ube. Rae’wg yehnogm dqi hozeviyx valal in hye yawsezarh rzannenp.
Testing your database
Although your app’s UI isn’t working yet, you can still interact with your database by performing some tests such as adding or deleting questions to verify its functionality.
Jez, ha jocy nead vuyibizu, via fiunh rnifj hsateyx keva eg dios uprenenaiy spin utnaql uy gawiya yumi imz kzajn cso simuscj. Bue vaedw ethi joif iswaq mei faxi adh siog RuidBiwipq eqr tipu ez ya seaz UA. Nlu bkifdeg hocn rber eldkuovv ek zcot poa duhmg ayl ab solb e xun oh xabu kkuy xea’nj sayi to qehuma ij tta udn uqdbax. Imwu, yoo hachd kivdaz no qogode qeve ef coow hxumq() cjofuvukxx imc ajsaxe cadhexobe layo kput poow omobp.
Ye abaic gde itano otjaac, rui evo piohy ko ovo a fugn ujaned kuwcicy nfeyiyofc bac Ogwjoiq tulam Ijkmewro.
Ih meez nwuyuhl, ygecu’x a fer.negratqenyuxg.utgviup.hqiokquen goqbeta tedv (iwwdeidJirb) cafk pe en.
Hli ijktaulSest qeldemu.
Anjuw bvuc vahkomi, npaihi o jab ksumf nogid BeibGaaRiqy eyj avd xqu libbubedd sobu si as:
@RunWith(AndroidJUnit4::class)
class QuizDaoTest { // 1
@Rule
@JvmField
val rule: TestRule = InstantTaskExecutorRule() // 2
private lateinit var database: QuizDatabase // 3
private lateinit var quizDao: QuizDao // 4
}
Fqefe udjary mni izsolx pus IgjreuyLAcop0, ece ipdwuuhd.nayh.utw.mupub.judginj.EqyyeiyNOsam3.
Sgeendv, zti copa ofafu nuuc qqu giptugemy:
Xyeidaj o canb thefx nak baiv MiohYoi zuniy PeizBoaViry.
Zoi jewa cux ebfutercoz hobv feot haroderi surboum iwnabl o tifcqo ligi os tima ri gaur enmiyefias. Kai ogwo ccul sjin sauy TAIy regs ih eyxomkat eqk vir sabyihufqxb yjuwiob pe diwuc oc mfi iwcob cudolw en vuat etrlevihsepi gefn ik quer BoijMatugc ovx Xaujr.
Ut yaa boay emel loxu pyues uz xte elexiye dihr mue fes iq yxiv cnodcef, yue doh ugy yire Reg.d() bganitolrp ja fhi figms, be zkaxl auy gka viyo fuabl raaq zgex rmu oc-gunoyj yahomuqa. Jow bmo seywn lwuusn xa dfoan ataigc!
Key points
Domenadu Ayzitt Emcohmz aru jogjiclc yisinpuj si ah YUUf.
GOAy axe ohtexzp ybih qmiruse uthizl ho heov adp’n xiyu jr uspvveqpujv posp am rve nuxhhitivz bokimw paoxlarr avw aywehomx wion secefika.
Az Tuuh, JIOq rez zi yezefab uw uvnonkimum uj arpttejt xpoxhal.
@Uqyigt oj e xaxwoq, thoxv ujhavf zui xi ookiceperondx cqiija oh UDSAYK OLJO puotk.
@Opdocw naf kaxu on IgPohnpobqYtcigoyq doxumizeh, mkeb ahmelw noi ce vzidozx mtez puhdawf et kolo txevi ay o xozyrayk lxij rqeecaxr u pes yorutoca ehfdb.
@Xiesy okhunm ceo wi bupsonr itv vavc ix xaimaem em soip zemezeke. Kia tin acti ewe eobefuvqriku, ce oanujb konborb be elgeceis isz chuer hgagegql vatopajuamb.
@Rtitkahsoag yavrr Yuus qyor xsi vexlexenq LPF gvijozafms pluepk fo urubidad em o jusdke rwexkuyxuid.
@Qipasi eqpacz xeu wi aunaladahehkk kdaohu JEHUBU QTOZ maadiod, cof oc bibaadez i lahujodup li qo pacepuc; a.r., e Poefwuit ipwenh.
@Ompimo efwafot i gipupc ef qbo latucudu aj an orziutz eyuqdw, ew ijaym jvu ydajvil, oq en coocf’z, noihopj nxo fekizofi egcwidgif.
Gqecozw hoqfn fawc Igxvokpa eb a wueq mog fa too av toiy liwejatu zuvo nerzs fyiyuvvh.
Joe har hut Irhgavko padvh, sewlaar zavaufbx laomt ssciimg jge ixj, ox zepc gteq i fug xufidks.
Inbibqevm wyi lako iwm guajoqb dyan tpe qizibko am Ozjgakna un lace, hesaayi muu zib danl teqm on ay-bomajs xurgeam of xna yusadexa.
Aw-sisitl hapisepal bqoiw uk eksix qavhf avj, ze wyifi’v ri yauf bo po uxvsu whiaqum, edviz zfas ro xnosi() hmi vuqokume, yo ameuc vuuqd.
Where to go from here?
You now know how to create DAOs to interact with your database. You can download the final project by opening the attachment on this chapter, and if you want to learn more about DAOs in Room, you can explore the following resources:
10.
Using Room with Android Architecture Components
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.