Android Room Tutorial: Zjednodušení práce s daty aplikací

Informace jsou pravděpodobně nejdůležitějším zdrojem, kterému uživatelé aplikací důvěřují. Vývojářům aplikací tyto informace říkají, kdo je uživatel, což nám dává možnost poskytovat dobré uživatelské prostředí (UX). Také tím, že na tyto informace aplikujeme obchodní pravidla, definujeme chování, které by aplikace měla mít. Tyto informace mohou být citlivé a odhalovat soukromé údaje uživatelů, proto je velmi důležité, abychom s nimi správně nakládali a zajistili jejich integritu, soukromí a správné uložení. V rámci tohoto návodu pro Android Room vám ukážeme, jak můžete s těmito daty snadněji pracovat a zároveň zajistit jejich integritu a bezpečnost, a to vše pomocí aplikace Room. Room je součástí komponent architektury systému Android.

Potřebujete Room?

Když mluvíme o trvalém ukládání informací v systému Android, nejdůležitější a „nejjednodušší“ možností je použití obyčejného SQLite. Mít dobrou implementaci databáze pomocí SQLite však znamená vygenerovat spoustu kódu, který nepřináší skutečnou hodnotu. Následná architektura často není tak čistá a přehledná, jak by mohla být.

Mohli byste také použít objektově-relační mapování neboli ORM, ale stejně budete muset ručně definovat a vytvořit databázi, podtřídit SQLiteOpenHelper a vytvořit smluvní třídy.

Takže otázka zní: Existuje nějaký způsob, jak celý tento proces zjednodušit? Odpověď zní: Ano, místnost je vaše řešení.

Blíže o Roomu a jeho fungování

Room je jedním z nejdůležitějších nástrojů v architektonických komponentách systému Android. Byl vydán na konferenci Google I/O 2016 a je to výkonný nástroj pro ukládání a manipulaci s informacemi v aplikacích pro Android. Poskytuje velmi snadný způsob práce s daty a vždy zajišťuje jejich bezpečnost a integritu.

Room není ORM; místo toho je to celá knihovna, která nám umožňuje snadněji vytvářet databáze SQLite a manipulovat s nimi. Pomocí anotací můžeme definovat naše databáze, tabulky a operace. Room tyto anotace automaticky převede na instrukce/dotazy SQLite, které provedou odpovídající operace do databázového stroje.

Tři hlavní součásti Roomu jsou:

– Entity: Reprezentuje tabulku v rámci databáze Room. Měla by být anotována pomocí @Entity.

– DAO: Rozhraní, které obsahuje metody pro přístup k databázi. Anotuje se pomocí @Dao.

– Database: Reprezentuje databázi. Je to objekt, který drží připojení k databázi SQLite a všechny operace se provádějí jeho prostřednictvím. Je anotován pomocí @Database.

Architektura místnosti vypadá následovně:

Android Room architektura

Příliš mnoho řečí-Podívejme se na příklad

Ponořme se do tohoto výukového programu Android Room. Představte si, že potřebujeme vytvořit aplikaci pro ukládání rutiny v posilovně. V naší databázi budeme mít čtyři entity, jak si ukážeme níže. Celý ukázkový kód je napsán v jazyce Kotlin (pokud Kotlin neznáte nebo se o něm chcete dozvědět více, zvu vás k přečtení mého článku o něm).

Nejprve musíme aktualizovat náš soubor gradle. Měl by vypadat takto:

apply plugin: 'com.android.application'apply plugin: 'kotlin-android'apply plugin: 'kotlin-android-extensions'apply plugin: 'kotlin-kapt'android { //.. Omitted since it is not relevant for the example}dependencies { //... some dependencies were omitted due to they are not relevant for the example def room_version = "2.2.0-rc01" implementation "androidx.room:room-runtime:$room_version" kapt "androidx.room:room-compiler:$room_version" compile 'com.google.code.gson:gson:2.2.4' implementation 'io.reactivex.rxjava2:rxandroid:2.0.2' implementation 'io.reactivex.rxjava2:rxjava:2.1.17'}

Podívejme se a analyzujme každou ze tří hlavních komponent Room: Entity, DAO a Databáze.

Entity

Pro náš příklad budeme používat čtyři entity:

Pohlaví, Cvičení, Rutina a Stážista.kt

Představuje pohlaví cvičence

@Entitydata class Gender( @PrimaryKey(autoGenerate = true) val id: Int? = null, val name: String)

Všimněte si:

– Všechny třídy, které představují entitu databáze, musí být opatřeny anotací @Entity

– Anotací @PrimaryKey(autoGenerate = true) naznačujeme, že id je primárním klíčem entity a měl by být automaticky generován databázovým strojem.

Cvičení.kt

Představuje cvičení, které je součástí rutiny.

@Entitydata class Exercise( @PrimaryKey(autoGenerate = true) val exerciseId: Int, val name: String, val repetitions:Int, @ColumnInfo(name = "machine_name") val machineName: String, val liftedWeight: Int)

Všimněte si:

– Ve výchozím nastavení používá Room názvy polí jako názvy sloupců v databázi. Pokud chcete, aby měl sloupec jiný název, přidejte k poli anotaci @ColumnInfo.

Routine.kt

V podstatě kontejner cvičení, která dohromady tvoří rutinu cvičení.

@Entity(tableName = "traineeRoutine")data class Routine( @PrimaryKey(autoGenerate = true) val routineId: Int, @ColumnInfo(name = "due_day") val dueDay: Date, @TypeConverters(ListConverter::class) val exercises: List)

Věci, kterých si všimněte:

– Pokud je třída anotována pomocí @Entity, bude název tabulky odpovídat názvu třídy. Pokud chceme použít jiný název, musíme spolu s anotací @Entity přidat vlastnost tableName.

– Anotaci @TypeConverters musíme použít, když deklarujeme vlastnost, jejímž typem je vlastní třída, seznam, typ data nebo jakýkoli jiný typ, který Room a SQL neumí serializovat. V tomto případě používáme anotaci na úrovni pole třídy, přičemž ji bude moci použít pouze toto pole. V závislosti na tom, kde je anotace umístěna, se bude chovat jinak, jak je vysvětleno zde.

Trainee.kt

Představuje vlastníka rutiny.

@Entity(indices = , foreignKeys = , childColumns = )])data class Trainee( @PrimaryKey(autoGenerate = true) val id: Int, val name: String, val age: Int, val gender: Int?, @Embedded val routine: Routine)

DAOs

Objekty přístupu k datům (DAOs) se používají pro přístup k našim datům, když implementujeme Room. Každý DAO musí obsahovat sadu metod pro manipulaci s daty (vkládání, aktualizace, mazání nebo získávání).

DaO může být implementován jako rozhraní nebo jako abstraktní třída. V našem případě používáme rozhraní. Protože všechny DAO jsou v podstatě identické, ukážeme si pouze jednu.

GenderDao.kt@Daointerface GenderDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertGender(gender: Gender) @Update fun updateGender(gender: Gender) @Delete fun deleteGender(gender: Gender) @Query("SELECT * FROM Gender WHERE name == :name") fun getGenderByName(name: String): List @Query("SELECT * FROM Gender") fun getGenders(): List}

Několik věcí, kterých je třeba si všimnout:

– Všechny DAO musí být anotovány pomocí @Dao.

– Funkce anotovaná pomocí @Insert, @Update nebo @Delete musí jako parametr obdržet instanci požadované třídy, která představuje objekt, který chceme vložit, aktualizovat, resp. smazat.

– V případě operací insert nebo update můžeme použít vlastnost onConflict, která udává, co se má udělat, když dojde ke konfliktu při provádění operace. K dispozici jsou tyto strategie: REPLACE, ABORT, FAIL, IGNORE a ROLLBACK.

– Pokud chceme získat konkrétní informace z jedné nebo více entit, můžeme funkci anotovat pomocí @Query a jako parametr zadat SQL skript.

Database

Zobrazuje databázi. Udržuje spojení s aktuální databází SQLite.

AppDatabase.kt@Database(entities = , version = 1)@TypeConverters(DateTypeConverter::class)abstract class AppDatabase : RoomDatabase() { abstract fun exerciseDao(): ExerciseDao abstract fun genderDao(): GenderDao abstract fun routineDao(): RoutineDao abstract fun traineeDao(): TraineeDao companion object { var INSTANCE: AppDatabase? = null fun getAppDataBase(context: Context): AppDatabase? { if (INSTANCE == null){ synchronized(AppDatabase::class){ INSTANCE = Room.databaseBuilder(context.applicationContext, AppDatabase::class.java, "myDB").build() } } return INSTANCE } fun destroyDataBase(){ INSTANCE = null } }}

Všimněte si zde:

– Jedná se o abstraktní třídu, která musí rozšiřovat třídu RoomDatabase.

– Musí být anotována pomocí @Database a dostává seznam entit se všemi třídami, které tvoří databázi (všechny tyto třídy musí být anotovány pomocí @Entity). Musíme také uvést verzi databáze.

– Pro každou z entit obsažených v anotaci @Database musíme deklarovat abstraktní funkci. Tato funkce musí vrátit odpovídající DAO (třídu s anotací @Dao).

– Nakonec deklarujeme doprovodný objekt, abychom získali statický přístup k metodě getAppDataBase, která nám poskytne singletonovou instanci databáze.

Konvertory typů

Konvertory typů se používají, když deklarujeme vlastnost, kterou Room a SQL neumí serializovat. Podívejme se na příklad serializace datového typu ‚date‘.

DateTypeConverter.ktclass DateTypeConverter { @TypeConverter fun fromTimestamp(value: Long?): Date? { return if (value == null) null else Date(value) } @TypeConverter fun dateToTimestamp(date: Date?): Long? { return date?.time }}

Použití databáze Room

Nyní se podíváme na velmi jednoduchý příklad použití databáze Room, kterou jsme právě vytvořili:

MainActivity.ktclass MainActivity : AppCompatActivity() { private var db: AppDatabase? = null private var genderDao: GenderDao? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Observable.fromCallable({ db = AppDatabase.getAppDataBase(context = this) genderDao = db?.genderDao() var gender1 = Gender(name = "Male") var gender2 = Gender(name = "Female") with(genderDao){ this?.insertGender(gender1) this?.insertGender(gender2) } db?.genderDao()?.getGenders() }).doOnNext({ list -> var finalString = "" list?.map { finalString+= it.name+" - " } tv_message.text = finalString }).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe() }}

Co budeme dělat?

– Získání instance databáze a GenderDao.

– Vytvoření dvou instancí Gender:

– Vložení obou vytvořených instancí do databáze.

– Dotaz na databázi, abychom získali všechna pohlaví v ní uložená.

– Sloučení názvů všech pohlaví, které jsme získali z databáze, a nastavení textu TextView touto hodnotou.

Prostor, abychom udělali více s méně

Prostor je jedním z důležitých prvků architektonických komponent systému Android. Poskytuje nám velmi robustní rámec pro práci a trvalé informace a vždy zajišťuje bezpečnost a integritu dat. Vývojářům také poskytuje snadné použití, takže mohou psát čitelný a srozumitelný kód. Pokud chcete udělat více s menším množstvím kódu a také zajistit bezpečnost uživatelských dat, měli byste jako vrstvu perzistence ve své aplikaci používat Room.

A to je vše! To je téměř vše, co potřebujete vědět k vytvoření a používání databáze v systému Android pomocí aplikace Room. Celý kód tohoto projektu získáte zde. Děkujeme, že jste si přečetli tento návod pro Android Room!

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.