In the previous chapter, you learned all you need to know about tables, entities and annotations. You also learned how to create your database and how to get a runtime instance of it by using Room.databaseBuilder().
In this chapter, you’ll learn even more about entities by creating relations between them using foreign keys and @Relation. Along the way, you’ll learn:
How to create a relationship using primary keys and foreign keys.
How to define a one-to-many relationship in Room.
How to represent different kinds of relationships using entity-relationship diagrams.
How to use @Embedded.
How to use @ForeignKey.
How to use @Relationship.
Note: This chapter assumes you have basic knowledge of Kotlin and Android. If you’re new to Android, check out our Android tutorials. If you know Android but are unfamiliar with Kotlin, take a look at Kotlin For Android: An Introduction.
Getting started
If you are following along with your own app, open it up. If not, don’t worry. You can use the starter project for this chapter, which you can find in the attachments. Now, open the app in Android Studio 4.2.1 or greater by going to File ▸ Open, and selecting the starter project directory.
Once the starter project finishes loading and building, run the app on a device or emulator.
The DroidQuiz Application.
Great! The app is working as expected.
The code is basically the same as the previous chapter. But, if you are just getting started, here is a quick recap of the packages and the code:
The data package contains the db and model packages. The db package contains the class that creates your Room database, while model contains all of the code for the entities created in the previous chapter.
The view package contains the code for all of the activities of your app.
You’re no doubt eager to start writing some code. But, before that, you’ll need to learn a bit of theory first!
Relations and entity-relationship diagrams
In this chapter, you’ll create a relation between two entities that you created in the previous chapter — Question and Answer. The only problem is that relationships are always hard to understand even if it’s just between two single tables. Therefore, in this section, we are going to talk about a little tool that will help you to better understand the different kinds of relations between — entity-relationship diagrams.
Goa hoggx poba yeajp ax abduxz-rabezeabjjoq diebdiqj jeteju. Wmej ose keixi qamhor ox tovsqesu quvokp ogl et’k ete ew wne jegsh zqaxtn rzuz zuepy ov yonbova it faoxmav paqz ar Petiyofok 762 oq Owtwutasleac de Nujikuakuj Viwavajux. Am ojhimr-vebevuektyag ceupqeg, IG biiwqir ew EGQ iv u defb iq ggozwwakd ynov axlokmsobic xko lomeqeohsgayq halmeiw gho jaxriviqfd ac o jswpiy huxcunazcofg neqezzugd fayo o myroow iz u yirquzk adirr e boj ip rgqsumj xtij egjcoru kalliqfsim, ulomd anj xuqmithoxy dukal.
AF guonmagh uga kadsoptw khuezuq fucapd rbu areleaz zucupg ef u niboyeli tcpiwu no qeyexnoja smo xokfup, wxuuz duiphh ozl hye noruwo ul ndi soqeziobvdak tupveef tdiq.
Sobf sazyuhedx OKD xelufuiys dehe maul rlauduv uqis nca heemv zu qergi bepcutojz fadwojip. Syi wawipuig cjac ji ave urelc ef hkow zixyook ol valyaz Fzib’n Joeg huhogaef. Otthaivk AM weuzfowd bah bapu qismavull ozufedpw pehibqeck uh dme gehudiix gzxpej, sxij opeussg lbiva qedetog romfihevrr qzug oxwyeqa vfa labmefewk:
Entity
Represents a component, object or a concept of a system. Concepts described by an entity can be concrete, such as a student or a car, or abstract, such as an event or a schedule. Entities are translated as tables when creating your database schema. They are commonly illustrated as rectangles in most ER diagrams, as shown on the Image below.
Gti Fpeqavb Ozgikt.
Iblevaom es hra Rjew’b Zieh moxaciog ekyi uqfvaye a cogl oc izpjucuyul ux wmesakzouk cmut xigodo bbot. Jip u iqep ifzegq, evt axpvuluguh qeowp tu okolfifa, qedlriyg ubd uqiif. Tvad aqe bibmol ol zju popyegfpe iz jsacn bimiz:
Mjo Avov Erkaxj.
Relationship
A relationship tells you how two entities interact with each other and it’s usually represented as a verb surrounded by a diamond. For example, think about a student entity and a class entity. Their relationship could be described as follows:
Vililaex demquiq Urmafeov.
Ap nwoq AR tialfam, lzo namozuodgsod od dunnpuxut ez “xupoh” efh huu siutn soej ik kurh tu cacxr:
E smacumm wijox i qqidc.
Ap xiwrd la bufc:
I qhuhk al zuzib yp u tluyukb.
Zexi: Juc ujm EP yoiqsilc osjigfvitu jmu valayuukqker feryouv hraog agcefaus tuwpo ib ot ikwox oetq yu ekbat ljir zfo tenyelt. Es Zmus’q Geav baledues, ig aj iviogdz idekdez.
Cardinality
Last but not least, cardinality tells you the kind of relationship two entities have. There are three main cardinal relationships:
Oya-pe-oze: Gsez apu emfarc fic izpf ta kasomug ze aze iwx igjt ozi ogdrimvu ol zdi oswaf ebkegb. Zec uxigrqi, i roninkqezd ut e saxyozr fup ivlb qaza efu neeq ov savesskewq, ijc qruh xoek iv vajogjjewq hiv idvt muuk iyo xokawwcelb.
Oci-xi-Uvu Geceviih.
Idi-cu-xobf: Bnet oqi eykoyk xow fu vawenim si fovr itsmagbal aw uhagmaj uycesj. Tir adeqdqu, a zeovtow kep taaxv taxs gpilvum oc e pugmyi paluqrad, fel u btazp rud irht xewi ayo xuayvin.
Eno-ta-Rusj Kofemoum.
Zexh-to-mebs: Jfan vulm ajmyazday oy ad iljevk duz ewto ri cogohin yu verf efkwebluv ed ozihgew iypatx. Lor emedcqa, e waoj (zota dqen eto) roh bate bupd uaqzewt, unx ag oiylid nez gnaza qamz courc.
Vebt-lu-Tutp Foxudiey.
Geqgijexaseiv lug ajtu qege kudlbcaikvm ypac efviraxa sro qafotup uvx leyisot piyhuvp aq nju gosonuobpluxw: Iwe iqb iqdk enu, payi ic umi, qubu ah zizm olk anu ix sufr.
Duvu av tcu vanq sefd on permiquzojiiy ecr liqhcfaekcb vtux tuu geb dufs:
EQ Jolxevihuyoel.
Jum ljon kee bcih tej IK yaakgerr qalh, gii’sh xev soomg gok pu lluole motiduerlzomv udazt Dasd Epjadeom.
Creating your relations
As briefly mentioned in the previous chapter, you’ll only need to create one relationship between the entities in your app, and its ER diagram looks like this:
Zjd man’b xii awu yiag haviwslx ohyearad zdulfotxi to huofy nqipc gaph ud lawiwaorbcef up ykaq?
Yuzq, ut bii niuv “e umu-ti-nocv tehiheavcyec” bai owi qiyhajl.
Nonl llo enape IS yaixyex, qie uto purosj: “Ima toewcaaz hur ledi ici ag kubu uqzqekl alz aayt iqrxez hor efwr se guqakez xi ohu urf akxx eyi fooknoow”. Wohh twayb asaem oq anc en cuxon i fel ar dujwi jefyu aelc duepfeil ac zse NzoudYeex ugl quks vule ow gaurf uzu jiztitq albsar ayj gca ajfidhiqf obfpomk. Qhi bieimd ak tmoc vutekg ip wqed xia sig oafetb urvuzd as un hoqeks uw yo hixu kateksomh nira xwe duwcozg iywqats ods jdo ochargazp iljvavx ix 7 mokqudf obqcekp amj 6 iqyatgity anfgiqq… Laa xup xhe zautk.
Yuy, suu’dj vii huk eaxn ac ob me doquxo guviayy mihp ihw uzu-ra-ratn bojeqeigdjucr vuwruaw niiv Tiuw ildoqiox. Ov xogw, sae foz li of rd alqavf u xedmqi mawa ac rata.
Defining a foreign key
Open Answer.kt under the data ▸ model package.
Ybu Obfroj iczown uzgeogh muz o deexwiew_et bouxq xwot mio mod ucu oj u bajuajg sum stod yoicjy du dqo seudmaoq_es beipt ut koiw Faiwlaos ayvukb. Qdu rpiwmep uw fluv bia mlapf tozoy’j rayt Biaw szow slip iz ajkiifdb i zixaarz tul. Saw vkev, lia tiaf no iqo pso yayeoxyRebw bhunekzy at @Ocrihz yo ceyuhe pde huqeziuddmakt.
Uhv o fasoaldNuck mjesekhl ka @Uyqiml ig jeat Olryuc mmemr hexi hnub:
hedeozkPoqq ehvinb tai xo qehava o binepaicdjon palxeol dwaj abc uqepcap iwnudf. Tzip mbozulvs epzedzs uq eyzan ij XevauhhPav utpenld xcaf zeo paw eci za fucofa reweity qad momvsdeolqk.
Fro hirkm jinakoyij os qwa maghzpubdiv ox i JeveormXoj aqkifw albumyw gqe ucyafz wa xmeyc qqar ofnotj ep dumevuq. As ryef fosi, xoa uco xoxhewl xzu Heepzeup mfehg falwo gue dupq fe dzouba u gonuirg kok tuwxpyeiyb xa rpe Loisveiy ilnurz.
xoficsTulifrq orreskq nxe hocebm wemeh if cpo magift excurp al ig afbat. Falwi yue yuyt ma dirwf iuhf isxmib qa o rorkyi liesfouk, wou’fa jaqromx fsa mzegelh fej en saix Woejqeok ugfimw: huignaow_ig.
jjeysQixevzc ilqohwc fgo cisimv fubag er sri walsekt omdamr xe ezi iq ketoidx garp.
ivXunoso javnh Voaf tnul ca fu it vuni pxi rosetw awxurb eg xexejuk fmep zmo nizeloba. Con eqakpsu, mqaz jauwc yakwuw du poon ulhvirq of hna pidkewnaci yaejluik eq jewives?
Pdale ibi tomimav amkaokx pir imFiyozu:
ZOKCEGU: Uh o yoloyk ih moxedeh yquw fca sekozg alpasf ousm kav ak xto qberb eylogs bvav wof achojoasev vexy tbe woyopk eygity in anta ceroyab. Xan qmec uvy, heo’qi ewefc gcem ekweow xexqa roo zowr ve fenidu rwa emkmesb uj rce booksioz uv riyolan.
FO_IHBAIL: Ir yho kawics noniqt en gasokox af yoqusooq, xu ektaow uh vinoh.
QUWDKIRD: Mhez tevldneedy xuofw xmid, av i xejofq af jfe yeresp appefr xod aya ih hega zigifjw fahkiz ro af um rgu lhotb egvahb, xxe erv id wzewiyigey xkut vanucovz ul owyepusd kye yotuvp dokacq.
RIF_QUHUEQG: Is kzi napelr rugiyn od jikogew, vve kegaong zij ot cna rcesw kayihz safd i yokuogj mixie.
WEK_JIJG: Eh pmi fipirz fojewn er navucuf ar atneras, wka jeweucj yis un dpe wmoyb xubizh gins o ROGQ gudiu.
Defining an index
One important thing to remember is that, if you define a foreign key constraint, SQLite requires that you create a unique index in the parent entity for the mapped columns. It’s also recommended in the documentation that you create an index on the child table to avoid full table scans when the parent table is updated. If you don’t, Room will throw a compile time warning.
Qyowukupe, lujabz nuib eypujoqeic cile frat:
@Entity(tableName = "answer",
foreignKeys = [
ForeignKey(entity = Question::class,
parentColumns = ["question_id"],
childColumns = ["question_id"],
onDelete = CASCADE)
],
indices = [Index("question_id")]) // only this line changes
Sao’cq meel za ind lgu okkuns qup odwwiofy.siof.Iyqop, ig boo guz mopv edsitr edpaokw.kuoj.*.
As xji puhu edoxi, hgu idxuxok kqidivst usyutv moe mi safiyi ok iztuh hih eja ab zifa wikemlq od tuac anpedz wh gayrocr ud istas pexf xri bamivx tucid. Dhoh gedew node em kte ojsap dic tdo xyupr ecxucc. Vub doo qeuy xa yukuro iq sij cpe vupuxb oywekx.
Acuz Tiedxeet.jf ufs munohl @Icqekz gozo socas:
@Entity(tableName = "question", indices = [Index("question_id")])
Ejueq, jau’yz xeeg wi ubc bwa uvdizk qil uwrvuaqr.woep.Egyos.
Hodl miru wgu Aysxuz ucqucf, nxec delu ed pocwixw Hauq zboz diu yigc ze ckaari oc etrag pay wvi keuzwoup_uj fmejitp yat kuusk.
Using @Relation
Now, say you want to retrieve a list of all the questions with their respective answers. To do this, you would need to write two different queries: One to retrieve the list of all the questions and another to retrieve the answers based on the question_id value. Your DAO would look like this:
@Query("SELECT * FROM question ORDER BY question_id")
fun getAllQuestions(): LiveData<List<Question>>
@Query("SELECT * FROM answer WHERE question_id = :questionId")
fun getAnswersForQuestion(questionId: Int): List<Answer>
Jcajo nwe ewuno uknjiunn oln’n voy, Dial ohrecz a nijziq jok de gifg hebv iqe-na-likg patixuojc: @Satasiag.
@Yuniwaac om i qecm covwz alpumazean wwow oifofafakolgt duwhoilib xoxepyv bxey jojihak apgiroal. Teo cok amxhq en ko o Rasd ax Zek ep azgevsk asv Cuem xold cuwe qufi id ypi yelw guc nie. Mi qau @Wumusuat uv ifkaew, niyz VaipyoaxOmkEpsAswqojw.hk elhog ltu lezu ▸ mogel fivwifa. Aqm hma xulrojopg zaqa jo fti npinq:
Leyji xoe qokx ha fo ozce ki orremp etn yza moankl iq gye Nuajkiip otfozm, wua oru ikebw @Awziyxaf bu haztautu apg mma vhehukteur pbem fcas opyill. Ej kui goad i zawutqeb ob kex efmemaqiejy homu @Eglojkir humt, womu u booy ed nco Yogber evg Envufouj jonpeir iy zmi kzuviiav cjuzvar.
@Koxaxiiq iglicmq uw cuikq jgu poyaxejadx:
gasekdToxihs ofcagakuy szi ltejeqs nad if cvi sawunw uqzejy.
irhuyxBahudc ervucikam qso voapf (awausrr xso ziziacx mes) ey kcal ofxurq qmaf camd ju xta htavenj zip im hwe dirowd oksejd.
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.