Room: mi ez, ORM könyvtár és munka SQLite-tal

Szerző: IT Sectr Megjelenés: 2026-03-12 Olvasási idő: 10 perc

A Room egy ORM könyvtár az Android Jetpack csomagból, amely absztrakciós réteget biztosít az SQLite felett a helyi adatbázisokkal való munkához Androidon. A hivatalos dokumentáció szerint Android Developers, 2025, a Room automatikusan generál DAO implementációkat annotációk alapján fordítási időben, ami körülbelül 70%-kal csökkenti a boilerplate kód mennyiségét a SQLiteOpenHelper közvetlen használatához képest. A könyvtár SQL lekérdezéseket ellenőriz a fordítási fázisban, lehetővé téve a szintaktikai hibák felderítését még az alkalmazás eszközön történő elindítása előtt.

Főbb pontok

  • Room — Android Jetpack ORM könyvtár, amely absztrakciós réteget biztosít az SQLite felett az adatok helyi tárolásához Android alkalmazásokban.
  • Három fő komponens: Entity (tábla leírása), DAO (adat műveletek) és Database (belépési pont az adatbázishoz).
  • SQL lekérdezések ellenőrzése a fordítási fázisban — kulcsfontosságú előny, amely lehetővé teszi a hibák megtalálását az alkalmazás telepítése előtt.
  • Beépített támogatás a Flow, LiveData és RxJava számára az adatbázis változásainak reaktív követéséhez.
  • A migrációs mechanizmus lehetővé teszi az adatbázis séma frissítését a már elmentett felhasználói adatok elvesztése nélkül.

Mi az a Room ORM könyvtár?

A Room egy ORM könyvtár az Android Jetpack csomagból, amelyet a Google hozott létre a helyi SQLite adatbázisokkal való munka egyszerűsítésére az Android platformon. Annotációkat biztosít az adatséma leírásához és automatikusan generálja a DAO interfészek implementációját a fordítási fázisban. Ellentétben a SQLiteOpenHelper közvetlen használatával, a Room felszabadítja a fejlesztőt a jelentős mennyiségű boilerplate kód írása alól az adatbázis kapcsolat létrehozásához, megnyitásához és kezeléséhez.

A könyvtárat a Google I/O 2017-en mutatták be az Android architektúra komponensek részeként. Azóta a Room a helyi adattárolás de facto szabványává vált, népszerűségben megelőzve olyan megoldásokat, mint a GreenDAO és a Realm Androidhoz. A Google adatai szerint a könyvtárat a Google Play-ben közzétett, helyi adatokkal dolgozó alkalmazások több mint 60%-a használja.

Kulcsfontosságú jellemző — az SQL lekérdezések ellenőrzése a fordítási fázisban annotációs processzor segítségével. Ha a fejlesztő hibát vét egy SQL parancsban, például nem létező oszlopnevet ad meg, a fordítás hibával végződik az alkalmazás telepítése előtt. Ez gyökeresen eltér a SQLiteOpenHelper megközelítéstől, ahol az ilyen hibák csak futásidőben, gyakran éles környezetben derülnek ki.

TypeConverter nem szabványos típusokhoz

Az SQLite csak öt adattípust támogat: TEXT, INTEGER, REAL, BLOB és NULL. Azonban Java-ban és Kotlin-ban összetett típusok használatosak: Date, List, Enum és egyedi objektumok. Ezek tárolására a Room a TypeConverters mechanizmust biztosítja — statikus metódusokat, amelyek az összetett típust a SQLite számára érthető primitív típussá alakítják. Például a Date objektum Long-á (timestamp), a List<String> pedig JSON stringgé alakul Gson vagy Moshi segítségével.

kotlin
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

val db = Room
    .databaseBuilder(context, AppDatabase::class.java, "app-db")
    .build()

A konverter deklarálásához elegendő a @TypeConverter annotációt hozzáadni egy statikus metódushoz és megadni a konverter osztályt a @TypeConverters annotációban adatbázis szinten. A Room automatikusan alkalmazza a konvertet a megfelelő típus olvasásakor és írásakor minden SQL lekérdezésben anélkül, hogy manuálisan kellene hívni a konverziós metódusokat.

A Room architektúrája: három kulcsfontosságú komponens

A Room három fő komponensből áll: Entity, DAO és Database. Mindegyik szigorúan meghatározott szerepet tölt be és a megfelelő annotációval van ellátva. Együtt egy teljes adathozzáférési réteget alkotnak, amely elkülöníti az alkalmazás üzleti logikáját a SQLite implementációs részleteitől.

Entity — adatbázis tábla

Az Entity egy adatosztály, amely egy tábla szerkezetét írja le az adatbázisban. Az osztály minden mezője megfelel a tábla egy oszlopának, és minden sor az adatbázisban az osztály egy példányának. A @Entity annotáció jelzi a Room-nak, hogy az osztály egy tábla. A @PrimaryKey annotációval ellátott mező határozza meg az elsődleges kulcsot, amely lehet auto-increment vagy összetett. A táblák közötti kapcsolathoz a @ForeignKey használatos, amely biztosítja az adatok integritását adatbázis szinten.

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

DAO — adat műveletek

A DAO (Data Access Object) egy interfész vagy absztrakt osztály, amely deklarálja az adatokkal való munkához szükséges műveleteket: beszúrás, olvasás, frissítés és törlés. Minden művelet @Insert, @Query, @Update vagy @Delete annotációval van ellátva. A Room automatikusan generálja ennek az interfésznek az implementációját a fordítási fázisban. Különös értékkel bír a @Query annotáció, amely SQL lekérdezést fogad stringként és ellenőrzi annak helyességét a build fázisban.

kotlin
@Dao
interface UserDao {
    @Insert
    suspend fun insert(user: User): Long

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

    @Query("SELECT * FROM users")
    fun getAllUsers(): Flow<List<User>>

    @Delete
    suspend fun delete(user: User)
}

Database — belépési pont

A Database egy absztrakt osztály, amely a RoomDatabase-ből származik, és belépési pontként szolgál az adatbázishoz. Tartalmazza az összes Entity listáját és absztrakt metódusokat biztosít a DAO eléréséhez. Az osztály @Database annotációval van ellátva, ahol a séma verziója és az entitások listája szerepel. Az adatbázis példányának létrehozása a Room.databaseBuilder segítségével történik az alkalmazás kontextusának, a fájl nevének és a Database osztálynak a megadásával.

Hogyan működik a Room az SQLite-tal a motorháztető alatt

A Room nem helyettesíti az SQLite-ot, hanem absztrakciós rétegként működik felette. A belső architektúra magában foglal egy annotációs processzort, kódgenerátort és kapcsolati poolt. A fordítási fázisban az annotációs processzor elemzi az Entity, DAO és Database osztályokat, majd létrehozza az implementációs osztályokat _Impl utótaggal. Az összes generált osztály a build csomagba kerül és nem látható közvetlenül a fejlesztő számára.

A kód generálása a fordítási fázisban — a Room központi mechanizmusa. Minden DAO interfészhez egy osztály generálódik az összes annotált metódus teljes implementációjával. A @Query annotációból származó SQL lekérdezések helyességét ellenőrzik: a processzor összeveti az oszlopneveket az Entity mezőkkel és ellenőrzi az SQL szintaxist. Hiba észlelése esetén a fordítás megszakad egy érthető üzenettel. Ez lehetetlen a nyers SQLiteOpenHelper használatakor, ahol a hibák csak futásidőben jelennek meg.

Kód generálása a fordítási fázisban

A generálási folyamat három szakaszból áll. Első — séma érvényesítés: a processzor ellenőrzi, hogy a @Database-ben felsorolt összes osztály érvényes Entity-e. Második — a DAO törzsének generálása: minden metódushoz egy implementáció készül a belső RoomSQLiteQuery objektum segítségével, amely előkészített lekérdezéseket hajt végre. Harmadik — a Database_Impl osztály generálása, amely megvalósítja az adatbázis létrehozását és megnyitását, valamint az összes DAO objektum inicializálását.

kotlin
class UserDao_Impl(private val __db: RoomDatabase) : UserDao {
    private val __insertionAdapter = __db
        .createInsertionAdapter(User::class, 0)

    override suspend fun insert(user: User): Long {
        __db.assertNotSuspendingTransaction()
        return __db.runInTransaction {
            __insertionAdapter.insertAndReturnId(user)
        }
    }
}

A Room nem hoz létre külön szálpoolt az adatbázis műveletekhez. Alapértelmezés szerint a lekérdezések a hívó szálban futnak egy korlátozással: az olvasás és írás blokkolja a szálat. Aszinkron munkához a Room integrálódik a Kotlin korutinokkal suspend függvényeken keresztül, a LiveData-val visszatérési értékeken keresztül és a Flow-val reaktív burkolókon keresztül. Ez rugalmasságot biztosít a fejlesztőnek az architektúra megoldás kiválasztásában egy adott feladathoz.

Példa a Room használatára Android alkalmazásban

Nézzünk egy gyakorlati példát egy jegyzetek tárolására szolgáló alkalmazás létrehozására a Room segítségével. Az alkalmazás egy Note táblát tartalmaz id, title, content és timestamp mezőkkel. A felhasználó jegyzeteket adhat hozzá, tekinthet meg és törölhet. A bemutatóhoz korutinok használatosak az aszinkron műveletekhez.

A Gradle függőségek konfigurálása

A Room Android projekthez csatlakoztatásához függőségeket kell hozzáadni az alkalmazás modul build.gradle fájljához. A Room három komponenst igényel: runtime könyvtárat, kapt annotációs processzort és opcionális korutin támogatást. A könyvtár verziója a room_version változóban van megadva a könnyű frissítés érdekében. A Room 2.4.0-tól kezdve a KSP támogatott a kapt alternatívájaként nagyobb build sebességgel.

groovy
dependencies {
    def room_version = "2.6.1"
    implementation "androidx.room:room-runtime:$room_version"
    kapt "androidx.room:room-compiler:$room_version"
    implementation "androidx.room:room-ktx:$room_version"
    // Opcionális: tesztelés
    testImplementation "androidx.room:room-testing:$room_version"
}

A függőségek konfigurálása után három fájl jön létre: a Note Entity, a NoteDao interfész és az AppDatabase osztály. A Note Entity @PrimaryKey és @ColumnInfo annotációkkal ellátott mezőket tartalmaz. A DAO metódusokat biztosít a beszúráshoz, lista lekéréséhez és törléshez. A Database a @Database annotáción keresztül kapcsolja össze az Entity-t és a DAO-t.

kotlin
@Entity(tableName = "notes")
data class Note(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    val title: String,
    val content: String,
    @ColumnInfo(name = "created_at")
    val timestamp: Long = System.currentTimeMillis()
)

@Dao
interface NoteDao {
    @Insert
    suspend fun insert(note: Note)

    @Query("SELECT * FROM notes ORDER BY created_at DESC")
    fun getAllNotes(): Flow<List<Note>>

    @Delete
    suspend fun delete(note: Note)
}

Az AppDatabase fájl egy absztrakt osztályként van deklarálva, amely a RoomDatabase-ből származik. A @Database annotációban szerepel a jelenlegi verzió összes Entity-je és a séma verziószáma. A példány eléréséhez singleton minta használatos a Room.databaseBuilder build metódusán keresztül az alkalmazás kontextusával. Az adatbázis példány gyorsítótárazása megakadályozza a többszörös létrehozást, amely memóriaszivárgáshoz vezethet.

Adatbázis migrációk a Room-ban

Migrációk a Room-ban egy mechanizmus az adatbázis séma megváltoztatására az alkalmazás frissítésekor a meglévő adatok elvesztése nélkül. Amikor a felhasználó telepíti a módosított Entity-kkel ellátott új verziót, a Room észleli a verzióeltérést és végrehajtja a megadott migrációs lépéseket. Migráció nélkül az adatbázis törlődik és újra létrejön, ami az összes elmentett felhasználói adat elvesztéséhez vezet.

A migrációt a Migration osztály írja le, amely az adatbázis kezdeti és végső verzióját fogadja. A migrate metóduson belül egy ALTER TABLE vagy CREATE TABLE SQL lekérdezés hajtódik végre a séma módosításához. A Room nem képes automatikusan érzékelni a séma változásokat — a fejlesztőnek manuálisan kell megírnia a migrációt minden Entity változáshoz. A Room 2.4.0 verziótól kezdve elérhető a kísérleti autoMigrations funkció a migrációk automatikus generálásához.

Automatikus migrációk autoMigrations segítségével

Az autoMigrations funkció lehetővé teszi a Room számára, hogy automatikusan generáljon migrációkat az Entity verziók közötti különbségek alapján. Használatához elegendő a @AutoMigration annotációt hozzáadni a @Database-hez és megadni a séma exportálását JSON-ba. A Room összehasonlítja a szomszédos verziók sémáit és létrehozza a szükséges ALTER lekérdezéseket. Azonban az autoMigrations csak visszafelé kompatibilis változtatásokat támogat: oszlopok hozzáadása, indexek létrehozása és típusváltások kompatibilis konverziókkal.

kotlin
val MIGRATION_1_2 = object : Migration(1, 2) {
    override fun migrate(db: SupportSQLiteDatabase) {
        db.execSQL(
            "ALTER TABLE users ADD COLUMN phone TEXT"
        )
    }
}

val db = Room
    .databaseBuilder(context, AppDatabase::class.java, "app-db")
    .addMigrations(MIGRATION_1_2)
    .build()

Összetett változtatások hozzáadásakor, mint például oszlopok átnevezése vagy táblák egyesítése, kézi migráció szükséges ideiglenes táblák használatával. Tipikus forgatókönyv: hozzon létre egy ideiglenes táblát a régi sémával, másolja az adatokat a régi táblából az újba konverziókkal, törölje a régi táblát és nevezze át az ideiglenest. A Room garantálja, hogy minden migráció egy tranzakcióban hajtódik végre, és hiba esetén a változtatások teljesen visszavonásra kerülnek.

Gyakran Ismételt Kérdések

Miben különbözik a Room a SQLiteOpenHelper-től?

A Room ORM absztrakciót biztosít annotációkkal és SQL ellenőrzéssel a fordítási fázisban, míg a SQLiteOpenHelper az összes lekérdezés kézi írását és a kapcsolatkezelést igényli. A Room automatikusan generál kódot a CRUD műveletekhez és integrálódik az Android architektúra komponensekkel, beleértve a LiveData-t és a Flow-t.

Milyen adattípusokat támogat a Room?

A Room támogatja az összes Java primitív típust: Int, Long, Boolean, Float, Double, valamint a String, ByteArray és Date típusokat. Az összetett típusokhoz, mint a List vagy Enum, TypeConverters használatos — statikus konverziós metódusok, amelyek a nem szabványos típusokat a SQLite által támogatott formátumokká alakítják.

Használható a Room korutinok nélkül?

Igen, a Room támogatja a szinkron hívásokat korutinok nélkül, de ezek blokkolják a szálat, amelyben futnak. Aszinkron munkához használható LiveData vagy RxJava a korutinok helyett. A Google a korutinok használatát ajánlja az adatok aszinkron elérésének fő módjaként új projektekben.

Mi történik migráció hiányában?

Ha a Room verzióeltérést észlel az adatbázisban és nem talál megfelelő migrációt, alapértelmezés szerint IllegalStateException keletkezik a hiba leírásával. A fejlesztő felülbírálhatja ezt a viselkedést a fallbackToDestructiveMigration metódussal, amely törli a meglévő adatbázist és újat hoz létre az összes adat elvesztésével.

Hogyan kezeli a Room a táblák közötti kapcsolatokat?

A Room támogatja a kapcsolatokat beágyazott objektumokon keresztül a @Embedded annotációval és kapcsolati osztályokon keresztül a @Relation annotációval. Összetett, táblák összekapcsolásával járó lekérdezésekhez egyedi POJO osztályok használatosak, amelyek mezői a @Query eredményeiből töltődnek fel az SQL JOIN operátor segítségével.

Összefoglalás

  • A Room — Android Jetpack ORM könyvtár, amely absztrakciós réteget hoz létre az SQLite felett az adatok kényelmes tárolásához az eszközön.
  • Az architektúra három komponensen alapul: Entity (tábla séma), DAO (műveletek) és Database (belépési pont).
  • Az SQL lekérdezések ellenőrzése a fordítási fázisban — a fő előny, amely kiküszöböli a futásidejű hibákat a lekérdezésekben.
  • Beépített támogatás a Flow, LiveData és RxJava számára lehetővé teszi reaktív architektúrák építését az UI automatikus frissítésével az adatok változásakor.
  • A Room-ban lévő migrációk biztosítják az adatbázis séma zökkenőmentes frissítését az elmentett felhasználói adatok elvesztése nélkül.
  • A könyvtár integrálódik a Kotlin korutinokkal a suspend függvényeken keresztül, egyszerűsítve az aszinkron adatmunkát.
  • Új projektekhez a Room a Google által hivatalosan ajánlott megoldás a helyi adattárolásra Androidon.

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is