Room: ano ito, ORM library at paggawa gamit ang SQLite

May-akda: IT Sectr Nai-publish: 2026-03-12 Oras ng pagbabasa: 10 min

Ang Room ay isang ORM library mula sa Android Jetpack na nagbibigay ng abstraction layer sa ibabaw ng SQLite para sa pagtatrabaho sa mga lokal na database sa Android. Ayon sa opisyal na dokumentasyon Android Developers, 2025, ang Room ay awtomatikong bumubuo ng mga implementasyon ng DAO batay sa mga annotation sa panahon ng compilation, na nag-aalis ng humigit-kumulang 70% ng boilerplate code kumpara sa direktang paggamit ng SQLiteOpenHelper. Ang library ay nagsasagawa ng pag-verify ng mga SQL query sa yugto ng compilation, na nagpapahintulot na matukoy ang mga syntax error bago patakbuhin ang app sa device.

Mga Pangunahing Punto

  • Room — ORM library ng Android Jetpack na nagbibigay ng abstraction layer sa ibabaw ng SQLite para sa lokal na pag-iimbak ng data sa mga Android app.
  • Tatlong pangunahing bahagi: Entity (paglalarawan ng talahanayan), DAO (mga operasyon ng data) at Database (entry point sa database).
  • Pag-verify ng mga SQL query sa yugto ng compilation — pangunahing bentahe na nagpapahintulot na makita ang mga error bago i-install ang app.
  • Built-in na suporta para sa Flow, LiveData at RxJava para sa reaktibong pagsubaybay sa mga pagbabago sa database.
  • Ang mekanismo ng migration ay nagpapahintulot na i-update ang schema ng database nang hindi nawawala ang naka-save na data ng user.

Ano ang Room ORM library?

Room ay isang ORM library mula sa Android Jetpack, na ginawa ng Google upang pasimplehin ang pagtatrabaho sa mga lokal na SQLite database sa Android platform. Nagbibigay ito ng mga annotation para sa paglalarawan ng schema ng data at awtomatikong bumubuo ng implementasyon ng mga DAO interface sa yugto ng compilation. Hindi tulad ng direktang paggamit ng SQLiteOpenHelper, pinapalaya ng Room ang developer mula sa pagsulat ng malaking halaga ng boilerplate code para sa paglikha, pagbubukas at pamamahala ng koneksyon sa database.

Ang library ay ipinakilala sa Google I/O 2017 bilang bahagi ng mga architectural component ng Android. Mula noon, ang Room ay naging de facto na pamantayan para sa lokal na pag-iimbak ng data, na nalampasan sa kasikatan ang mga solusyon tulad ng GreenDAO at Realm para sa Android. Ayon sa Google, ang library ay ginagamit sa higit sa 60% ng mga app na nai-publish sa Google Play na gumagana sa lokal na data sa device.

Pangunahing tampok — pag-verify ng mga SQL query sa yugto ng compilation gamit ang annotation processor. Kung ang developer ay magkamali sa SQL command, halimbawa, tumukoy ng hindi umiiral na pangalan ng column, ang compilation ay magtatapos sa error bago i-install ang app. Ito ay lubhang naiiba mula sa SQLiteOpenHelper approach, kung saan ang mga ganitong error ay natutukoy lamang sa runtime, madalas sa produksyon.

TypeConverters para sa hindi karaniwang mga uri

Ang SQLite ay sumusuporta lamang sa limang uri ng data: TEXT, INTEGER, REAL, BLOB at NULL. Gayunpaman, sa Java at Kotlin ay ginagamit ang mga kumplikadong uri: Date, List, Enum at mga custom na object. Para sa pag-iimbak ng mga ito, ang Room ay nagbibigay ng mekanismong TypeConverters — mga static na pamamaraan na nagko-convert ng kumplikadong uri sa primitibong uri na naiintindihan ng SQLite. Halimbawa, ang Date object ay na-convert sa Long (timestamp), at ang List<String> sa JSON string sa pamamagitan ng Gson o Moshi.

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()

Upang ideklara ang converter, sapat na magdagdag ng @TypeConverter annotation sa isang static na pamamaraan at tukuyin ang converter class sa @TypeConverters annotation sa antas ng database. Awtomatikong inilalapat ng Room ang converter kapag binabasa at sinusulat ang kaukulang uri sa bawat SQL query nang hindi manu-manong tinatawag ang mga conversion method.

Arkitektura ng Room: tatlong pangunahing bahagi

Room ay binubuo ng tatlong pangunahing bahagi: Entity, DAO at Database. Bawat isa ay gumaganap ng mahigpit na tinukoy na papel at na-annotate ng kaukulang annotation. Sama-sama silang bumubuo ng isang kumpletong layer ng pag-access ng data na naghihiwalay sa business logic ng app mula sa mga detalye ng implementasyon ng SQLite.

Entity — talahanayan ng database

Entity ay isang klase ng data na naglalarawan ng istraktura ng isang talahanayan sa database. Ang bawat field ng klase ay tumutugma sa isang column ng talahanayan, at ang bawat row sa database ay tumutugma sa isang instance ng klase. Ang @Entity annotation ay nagsasabi sa Room na ang klase ay isang talahanayan. Ang field na may @PrimaryKey annotation ay tumutukoy sa pangunahing key, na maaaring auto-increment o composite. Para sa relasyon sa pagitan ng mga talahanayan, ginagamit ang @ForeignKey, na nagsisiguro ng integridad ng data sa antas ng database.

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 — mga operasyon ng data

DAO (Data Access Object) ay isang interface o abstract class na nagdedeklara ng mga operasyon para sa pagtatrabaho sa data: pagpasok, pagbasa, pag-update at pagtanggal. Ang bawat operasyon ay na-annotate ng @Insert, @Query, @Update o @Delete. Awtomatikong bumubuo ang Room ng implementasyon ng interface na ito sa yugto ng compilation. Ang partikular na halaga ay taglay ng @Query annotation, na tumatanggap ng SQL query bilang string at sinusuri ang kawastuhan nito sa yugto ng build.

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 — entry point

Database ay isang abstract class na nagmamana ng RoomDatabase, na nagsisilbing entry point sa database. Naglalaman ito ng listahan ng lahat ng Entity at nagbibigay ng mga abstract na pamamaraan para sa pagkuha ng DAO. Ang klase ay na-annotate ng @Database, kung saan tinutukoy ang bersyon ng schema at listahan ng mga entity. Ang paglikha ng instance ng database ay ginagawa sa pamamagitan ng Room.databaseBuilder na may pagtukoy sa konteksto ng app, pangalan ng file at klase ng Database.

Paano gumagana ang Room sa SQLite sa ilalim ng hood

Room ay hindi pumapalit sa SQLite, kundi gumagana sa ibabaw nito bilang abstraction layer. Ang panloob na arkitektura ay may kasamang annotation processor, code generator at connection pool. Sa yugto ng compilation, sinusuri ng annotation processor ang mga klase ng Entity, DAO at Database, pagkatapos ay bumubuo ng mga implementasyon na klase na may suffix na _Impl. Lahat ng nabuong klase ay inilalagay sa build package at hindi direktang nakikita ng developer.

Ang pagbuo ng code sa yugto ng compilation — sentral na mekanismo ng Room. Para sa bawat DAO interface, nabubuo ang isang klase na may kumpletong implementasyon ng lahat ng na-annotate na pamamaraan. Ang mga SQL query mula sa @Query annotation ay sinusuri para sa kawastuhan: itinutugma ng processor ang mga pangalan ng column sa mga field ng Entity at sinusuri ang syntax ng SQL. Kapag may nakitang error, ang compilation ay naaantala na may malinaw na mensahe. Ito ay imposible kapag gumagamit ng raw SQLiteOpenHelper, kung saan ang mga error ay lilitaw lamang sa runtime.

Pagbuo ng code sa yugto ng compilation

Ang proseso ng pagbuo ay may kasamang tatlong yugto. Una — pagpapatunay ng schema: sinusuri ng processor kung ang lahat ng klase na nakalista sa @Database ay wastong Entity. Ikalawa — pagbuo ng katawan ng DAO: para sa bawat pamamaraan, nilikha ang isang implementasyon gamit ang panloob na RoomSQLiteQuery object na nagsasagawa ng mga prepared query. Ikatlo — pagbuo ng Database_Impl class, na nagpapatupad ng paglikha at pagbubukas ng database pati na rin ang pagsisimula ng lahat ng DAO object.

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)
        }
    }
}

Ang Room ay hindi lumilikha ng hiwalay na thread pool para sa mga operasyon ng database. Bilang default, ang mga query ay isinasagawa sa tumatawag na thread na may isang limitasyon: ang pagbasa at pagsulat ay humaharang sa thread. Para sa asynchronous na trabaho, ang Room ay sumasama sa Kotlin coroutines sa pamamagitan ng suspend function, sa LiveData sa pamamagitan ng mga return value at sa Flow sa pamamagitan ng reactive wrapper. Ito ay nagbibigay sa developer ng flexibility sa pagpili ng architectural solution para sa isang partikular na gawain.

Halimbawa ng paggamit ng Room sa Android app

Tingnan natin ang isang praktikal na halimbawa ng paglikha ng app para sa pag-iimbak ng mga tala gamit ang Room. Ang app ay naglalaman ng isang talahanayan na Note na may mga field na id, title, content at timestamp. Ang user ay makakapagdagdag, makakatingin at makakapagtanggal ng mga tala. Para sa demonstrasyon, ginagamit ang mga coroutine para sa asynchronous na mga operasyon.

Pag-configure ng mga dependency ng Gradle

Upang ikonekta ang Room sa isang Android project, kailangan magdagdag ng mga dependency sa build.gradle file ng module ng app. Ang Room ay nangangailangan ng tatlong bahagi: runtime library, kapt annotation processor at opsyonal na suporta para sa coroutine. Ang bersyon ng library ay tinukoy sa variable na room_version para sa kadalian ng pag-update. Simula sa Room 2.4.0, ang KSP ay sinusuportahan bilang alternatibo sa kapt na may mas mataas na bilis ng build.

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"
    // Opsyonal: pagsubok
    testImplementation "androidx.room:room-testing:$room_version"
}

Pagkatapos i-configure ang mga dependency, tatlong file ang nilikha: Note Entity, NoteDao interface at AppDatabase class. Ang Entity Note ay naglalaman ng mga field na may @PrimaryKey at @ColumnInfo annotation. Ang DAO ay nagbibigay ng mga pamamaraan para sa pagpasok, pagkuha ng listahan at pagtanggal. Ang Database ay nag-uugnay ng Entity at DAO sa pamamagitan ng @Database annotation.

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)
}

Ang file na AppDatabase ay idineklara bilang abstract class na nagmamana ng RoomDatabase. Sa @Database annotation, lahat ng Entity ng kasalukuyang bersyon at numero ng bersyon ng schema ay tinukoy. Para sa pagkuha ng instance, ginagamit ang singleton pattern sa pamamagitan ng build method ng Room.databaseBuilder na may konteksto ng app. Ang pag-cache ng database instance ay pumipigil sa maramihang paglikha na maaaring humantong sa pagtagas ng memorya.

Mga migration ng database sa Room

Mga migration sa Room ay isang mekanismo para sa pagbabago ng schema ng database kapag nag-a-update ng app nang hindi nawawala ang umiiral na data. Kapag nag-install ang user ng bagong bersyon na may binagong Entity, nade-detect ng Room ang hindi pagkakatugma ng bersyon at isinasagawa ang tinukoy na mga hakbang sa migration. Kung walang migration, ang database ay tatanggalin at muling lilikhain, na magreresulta sa pagkawala ng lahat ng naka-save na data ng user.

Ang migration ay inilalarawan ng Migration class, na tumatanggap ng simula at panghuling bersyon ng database. Sa loob ng migrate method, isinasagawa ang SQL query na ALTER TABLE o CREATE TABLE upang baguhin ang schema. Ang Room ay hindi awtomatikong matukoy ang mga pagbabago sa schema — ang developer ay dapat na manu-manong sumulat ng migration para sa bawat pagbabago ng Entity. Simula sa bersyon ng Room 2.4.0, ang eksperimental na function na autoMigrations ay magagamit para sa awtomatikong pagbuo ng mga migration.

Awtomatikong mga migration gamit ang autoMigrations

Ang function na autoMigrations ay nagpapahintulot sa Room na awtomatikong bumuo ng mga migration batay sa mga pagkakaiba sa pagitan ng mga bersyon ng Entity. Upang magamit ito, sapat na magdagdag ng @AutoMigration annotation sa @Database at tukuyin ang pag-export ng schema sa JSON. Inihahambing ng Room ang mga schema ng mga katabing bersyon at bumubuo ng mga kinakailangang ALTER query. Gayunpaman, ang autoMigrations ay sumusuporta lamang sa backward-compatible na mga pagbabago: pagdaragdag ng mga column, paglikha ng mga index at pagbabago ng mga uri na may katugmang conversion.

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()

Kapag nagdaragdag ng mga kumplikadong pagbabago, tulad ng pagpapalit ng pangalan ng mga column o pagsasama ng mga talahanayan, kinakailangan ang manu-manong migration gamit ang mga pansamantalang talahanayan. Karaniwang senaryo: lumikha ng pansamantalang talahanayan na may lumang schema, kopyahin ang data mula sa lumang talahanayan patungo sa bago na may mga conversion, tanggalin ang lumang talahanayan at palitan ang pangalan ng pansamantalang. Room ay ginagarantiyahan na ang lahat ng migration ay isinasagawa sa isang transaksyon, at sa paglitaw ng error, ang mga pagbabago ay ganap na ibinabalik.

Mga Madalas Itanong

Paano naiiba ang Room sa SQLiteOpenHelper?

Room ay nagbibigay ng ORM abstraction na may mga annotation at SQL verification sa yugto ng compilation, samantalang ang SQLiteOpenHelper ay nangangailangan ng manu-manong pagsulat ng lahat ng query at pamamahala ng koneksyon. Awtomatikong bumubuo ang Room ng code para sa CRUD operations at sumasama sa mga architectural component ng Android, kabilang ang LiveData at Flow.

Anong mga uri ng data ang sinusuportahan ng Room?

Room ay sumusuporta sa lahat ng primitibong uri ng Java: Int, Long, Boolean, Float, Double, pati na rin ang String, ByteArray at Date. Para sa mga kumplikadong uri tulad ng List o Enum, ginagamit ang TypeConverters — mga static na conversion method na nagko-convert ng hindi karaniwang mga uri sa mga format na sinusuportahan ng SQLite.

Maaari bang gamitin ang Room nang walang coroutine?

Oo, ang Room ay sumusuporta sa synchronous na mga tawag nang walang coroutine, ngunit hinaharangan nila ang thread kung saan sila isinasagawa. Para sa asynchronous na trabaho, maaaring gamitin ang LiveData o RxJava sa halip na coroutine. Inirerekomenda ng Google ang paggamit ng coroutine bilang pangunahing paraan ng asynchronous na pag-access sa data sa mga bagong proyekto.

Ano ang mangyayari kung walang migration?

Kung ang Room ay nakakita ng hindi pagkakatugma ng bersyon ng database at hindi makahanap ng angkop na migration, bilang default ay magaganap ang IllegalStateException na may paglalarawan ng error. Maaaring i-override ng developer ang pag-uugaling ito gamit ang fallbackToDestructiveMigration method, na tatanggalin ang umiiral na database at lilikha ng bago na may pagkawala ng lahat ng data.

Paano pinangangasiwaan ng Room ang mga relasyon sa pagitan ng mga talahanayan?

Room ay sumusuporta sa mga relasyon sa pamamagitan ng mga nested object na may @Embedded annotation at sa pamamagitan ng relation class na may @Relation annotation. Para sa mga kumplikadong query na may pagsasama ng mga talahanayan, ginagamit ang mga custom na POJO class na ang mga field ay pinupunan mula sa mga resulta ng @Query na may JOIN operator sa SQL.

Buod

  • Room — ORM library ng Android Jetpack na lumilikha ng abstraction layer sa ibabaw ng SQLite para sa maginhawang pag-iimbak ng data sa device.
  • Ang arkitektura ay batay sa tatlong bahagi: Entity (schema ng talahanayan), DAO (mga operasyon) at Database (entry point).
  • Pag-verify ng mga SQL query sa yugto ng compilation — pangunahing bentahe na nag-aalis ng mga runtime error sa mga query.
  • Built-in na suporta para sa Flow, LiveData at RxJava ay nagpapahintulot sa pagbuo ng mga reactive architecture na may awtomatikong pag-update ng UI kapag nagbago ang data.
  • Mga migration sa Room ay nagsisiguro ng maayos na pag-update ng schema ng database nang hindi nawawala ang naka-save na impormasyon ng user.
  • Ang library ay sumasama sa Kotlin coroutine sa pamamagitan ng suspend function, na pinapasimple ang asynchronous na trabaho sa data.
  • Para sa mga bagong proyekto, ang Room ay opisyal na inirerekomendang solusyon ng Google para sa lokal na pag-iimbak ng data sa Android.

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din