Room: klíčové pojmy, Entity, DAO a práce s databází

Autor: IT Sectr Publikováno: 2026-05-04 Doba čtení: 8 min

Room je knihovna pro práci s SQLite v Androidu, která je součástí Jetpack. Poskytuje vrstvu abstrakce nad čistým SQLite, automatizuje vytváření tabulek, provádění dotazů a převod dat na objekty Kotlin a Java. Podle Android Developers Room kompiluje SQL dotazy během fáze sestavení a kontroluje správnost syntaxe a vztahů mezi Entity a tabulkami.

Hlavní body

  • Room — ORM knihovna Jetpack pro práci s SQLite v Android aplikacích.
  • Entity — třída anotovaná @Entity, každá instance odpovídá řádku v tabulce.
  • DAO — Data Access Object s anotovanými metodami pro SQL dotazy.
  • Database — abstraktní třída dědící RoomDatabase, propojující Entity a DAO.
  • Migrace — mechanismus bezpečné změny schématu databáze bez ztráty dat uživatele.

Co je Room a proč je potřeba

Room je knihovna persistence z Android Jetpack, která poskytuje objektově-relační mapování pro SQLite. Room řeší tři hlavní problémy čistého SQLite: psaní velkého množství boilerplate kódu pro vytváření tabulek, chybějící kontrolu SQL dotazů v době kompilace a ruční převod Cursor na objekty.

Knihovna používá kompilátor anotací (kapt nebo KSP), který generuje implementaci abstraktních tříd RoomDatabase a DAO během fáze sestavení. To zaručuje, že syntaktické chyby v SQL a neshody typů jsou odhaleny před spuštěním aplikace, nikoli za běhu po publikování v Google Play.

Podle Google I/O 2023 je Room používán v 68% Android aplikací, které pracují s lokálními daty. Je to standard ukládání dat na zařízení, doporučený Googlem pro všechny nové projekty — namísto zastaralých SQLiteOpenHelper a ContentProvider.

Implementujte Room v projektech, kde je vyžadováno lokální ukládání dat z serveru do mezipaměti, offline režim nebo ukládání strukturovaných uživatelských dat s možností komplexních SQL dotazů.

Room je součástí Android Jetpack a je oficiálně doporučen Googlem pro všechny nové projekty pracující s lokálními daty. Na rozdíl od Realm nebo ObjectBox Room používá nativní SQLite, což zaručuje kompatibilitu s jakýmikoli nástroji třetích stran pro práci s databází — od DB Browser po DataGrip. Vývojář může otevřít .db soubor aplikace a provádět SQL dotazy přímo, což usnadňuje ladění a analýzu dat během vývoje.

Entity a anotace v Room

Entity je datová třída anotovaná @Entity, kterou Room přemění na tabulku databáze. Každé pole třídy se stane sloupcem tabulky a každá instance řádkem. Room používá reflexi pro přístup k polím, proto je vyžadována anotace @PrimaryKey pro povinný identifikátor.

Základní anotace

Anotace @Entity informuje Room, že třída je tabulka. Parametr tableName nastavuje název tabulky, pokud se liší od názvu třídy. @PrimaryKey definuje primární klíč s možností automatického generování pomocí autoGenerate = true.

kotlin
@Entity(tableName = "users")
data class User(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    @ColumnInfo(name = "full_name")
    val name: String,
    @Ignore
    val tempData: String?
)

@ColumnInfo nastavuje název sloupce v tabulce, pokud se liší od názvu pole Kotlin. @Ignore vylučuje pole z tabulky — nebude uloženo do databáze. @ForeignKey popisuje cizí klíče pro vztahy mezi tabulkami s kaskádovými operacemi při mazání nebo aktualizaci.

Room podporuje vnořené objekty prostřednictvím anotace @Embedded. Pole vnořené třídy se rozvinou do sloupců nadřazené tabulky s prefixem pro zabránění konfliktům názvů. Například třída Address s poli city a street, vložená do User, vytvoří sloupce address_city a address_street v tabulce users, čímž odpadá potřeba vytvářet samostatné tabulky pro jednoduché hodnotové objekty.

Typy konverzí

Room podporuje pouze primitivní typy a jejich obaly. Pro ukládání seznamů, Date nebo vlastních typů se používá @TypeConverter — statické metody převodu mezi vlastním typem a primitivem SQLite, například mezi List a JSON řetězcem.

DAO a SQL dotazy

DAO (Data Access Object) je rozhraní nebo abstraktní třída anotovaná @Dao, obsahující metody pro přístup k datům. Každá metoda je anotována SQL operací: @Insert, @Update, @Delete nebo @Query s explicitním SQL dotazem.

@Query s kontrolou v době kompilace

Anotace @Query přijímá SQL řetězec, který je Roomem kontrolován v době kompilace na správnost syntaxe a shodu názvů sloupců s poli Entity. Room podporuje parametrizované dotazy pomocí syntaxe :paramName.

kotlin
@Dao
interface UserDao {
    @Query("SELECT * FROM users WHERE id = :userId")
    suspend fun getUserById(userId: Int): User?

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertUser(user: User)

    @Query("SELECT * FROM users ORDER BY name ASC")
    fun getAllUsers(): Flow<List<User>>
}

@Insert podporuje strategie OnConflictStrategy pro zpracování konfliktů při vkládání duplicitních záznamů. Flow jako návratový typ zajišťuje reaktivní aktualizaci UI při každé změně dat v tabulce — odběr se automaticky restartuje při každém INSERT, UPDATE nebo DELETE.

@Transaction pro komplexní operace

Anotace @Transaction zaručuje atomické provedení více operací v jednom transakčním bloku. Room uzamkne databázi během provádění a zabraňuje race condition při současném přístupu z více vláken.

Database a migrace schématu

RoomDatabase je abstraktní třída, která spojuje Entity a DAO do jediného přístupového bodu k databázi. Vytváří se pomocí Room.databaseBuilder s uvedením verze schématu a seznamu tříd Entity. Instanci databáze se doporučuje vytvářet jako singleton pomocí lazy delegátu, aby se předešlo vícenásobným připojením.

Migrace

Migrace v Room je třída Migration popisující SQL skript pro přechod ze staré verze schématu na novou. Pokud není migrace poskytnuta při změně schématu, Room vyhodí IllegalStateException. To chrání před náhodnou ztrátou uživatelských dat při aktualizaci aplikace.

kotlin
val migration_1_2 = object : Migration(1, 2) {
    override fun migrate(db: SupportSQLiteDatabase) {
        db.execSQL("ALTER TABLE users ADD COLUMN age INTEGER NOT NULL DEFAULT 0")
    }
}

val db = Room.databaseBuilder(
    getApplication(),
    AppDatabase::class.java,
    "app_database"
).addMigrations(migration_1_2)
 .build()

Pro vývoj lze použít fallbackToDestructiveMigration, který při neshodě verzí smaže starou databázi a vytvoří novou. Tento režim je určen pouze pro ladění — v produkčních verzích se migrace povinně píší.

Pro testování databáze Room poskytuje speciální třídu Room.inMemoryTestBuilder, která vytváří databázi v RAM bez ukládání na disk. Po dokončení každého testu je databáze automaticky zničena, což zaručuje úplnou izolaci testovacích scénářů. V kombinaci s knihovnou android-arch-core-testing může vývojář spravovat životní cyklus databáze a kontrolovat správnost migrací bez nutnosti ručně čistit stav.

Výkon Room přímo závisí na struktuře dotazů a indexů. Pro analýzu pomalých dotazů Room poskytuje příznak enableQueryCallback, který loguje všechny SQL dotazy s dobou provedení. Vývojář může tento log použít k nalezení dotazů trvajících déle než 100 milisekund a optimalizovat je přidáním složených indexů pomocí anotace @Index v @Entity nebo přepsáním poddotazů na přímá JOIN spojení s využitím @Relation.

Room také podporuje šifrování databáze prostřednictvím SQLCipher. Připojení knihovny net.zetetic:android-database-sqlcipher a použití SupportFactory místo standardního zajišťuje transparentní šifrování všech dat na disku beze změny DAO dotazů a struktury Entity. To je nezbytné pro aplikace pracující s osobními údaji uživatelů a splňuje požadavky GDPR a ruského zákona 152-FZ o ochraně osobních údajů. Šifrovací heslo může být uloženo v Android Keystore pro ochranu před extrakcí pomocí nástrojů na rootovaných zařízeních.

Room s Kotlin Coroutines a Flow

Room nativně podporuje Kotlin Coroutines od verze 2.1. DAO metody mohou být suspend funkce provádějící dotazy na pozadí bez blokování hlavního vlákna. Room automaticky spravuje dispečery a používá Dispatchers.IO pro čtecí a zapisovací dotazy.

Pro reaktivní dotazy Room vrací Flow — studený datový tok, který emituje novou hodnotu při každé změně dotčené tabulky. ViewModel se přihlásí k odběru Flow pomocí stateIn nebo collect, což zajišťuje automatickou aktualizaci UI bez ručního oznamování adaptéru.

Room také podporuje Paging 3 prostřednictvím speciální implementace PagingSource, která načítá data po stránkách z SQLite. To je efektivní pro velké seznamy s tisíci záznamy: Paging 3 načítá pouze řádky viditelné na obrazovce a automaticky je aktualizuje při změnách v databázi.

Používejte Paging 3 s Room při zobrazování zpravodajského kanálu, protokolu operací nebo seznamu produktů s možností offline přístupu a nekonečným posouváním.

Často kladené otázky

Čím se Room liší od SQLiteOpenHelper?

Room automatizuje vytváření tabulek, převod Cursor na objekty a kontrolu SQL v době kompilace. SQLiteOpenHelper vyžaduje ruční psaní schématu, zpracování Cursor a nemá kontrolu dotazů před spuštěním aplikace, což zvyšuje riziko chyb.

Je nutné psát migrace pro každou změnu schématu?

Ano, při změně Entity (přidání/odebrání pole, změna typu) je vyžadována migrace. Bez ní Room při spuštění vyhodí IllegalStateException. Pro vývoj lze zapnout fallbackToDestructiveMigration, ale v release jsou povinné správné migrační skripty.

Podporuje Room vztahy mezi tabulkami?

Room podporuje @ForeignKey pro kaskádové operace a @Relation pro vnořené objekty. Pro komplexní JOIN dotazy se používá anotace @Transaction s @Query vracející POJO s vnořenými entitami pomocí @Embedded a @Relation.

Lze použít Room s Java bez Kotlin?

Ano, Room je plně kompatibilní s Java. Místo suspend funkcí se používají LiveData nebo RxJava Observable, místo Flow — LiveData. Room s Java podporuje všechny stejné anotace, ale vyžaduje více boilerplate kódu pro asynchronní operace.

Jak funguje šifrování databáze Room?

Room podporuje šifrování prostřednictvím SQLCipher od Zetetic. Místo Room.databaseBuilder použijte SupportFactory z knihovny net.zetetic:android-database-sqlcipher a předejte šifrovací heslo. Všechna data na disku budou transparentně zašifrována pro DAO dotazy.

Shrnutí

  • Room — ORM knihovna Jetpack pro SQLite s kontrolou SQL v době kompilace.
  • @Entity popisuje tabulku, @PrimaryKey — identifikátor, @ColumnInfo — název sloupce.
  • @Dao obsahuje metody s @Query, @Insert, @Update a @Delete pro přístup k datům.
  • RoomDatabase spojuje Entity a DAO, vytváří se pomocí Room.databaseBuilder.
  • Migrace (Migration) popisují SQL skripty pro změnu schématu bez ztráty dat.
  • Room nativně podporuje Kotlin Coroutines (suspend) a Flow pro reaktivní aktualizace UI.
  • Pro velké seznamy používejte Paging 3 s Room přes PagingSource pro stránkové načítání.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také