Room: кључни појмови, Entity, DAO и рад са базом података

Аутор: IT Sectr Објављено: 2026-05-04 Време читања: 8 мин

Room је библиотека за рад са SQLite-ом у Android-у, која је део Jetpack-а. Пружа слој апстракције над сировим SQLite-ом, аутоматизујући креирање табела, извршавање упита и конверзију података у Kotlin и Java објекте. Према Android Developers, Room компајлира SQL упите у фази изградње, проверавајући исправност синтаксе и веза између Entity и табела.

Главне тачке

  • Room — ORM библиотека Jetpack-а за рад са SQLite-ом у Android апликацијама.
  • Entity — класа анотирана са @Entity, свака инстанца одговара реду у табели.
  • DAO — Data Access Object са анотираним методама за SQL упите.
  • Database — апстрактна класа која наслеђује RoomDatabase, повезујући Entity и DAO.
  • Миграција — механизам безбедне промене шеме базе без губитка корисничких података.

Шта је Room и зашто је потребан

Room — је библиотека перзистентности из састава Android Jetpack-а која пружа објектно-релационо мапирање за SQLite. Room решава три главна проблема сировог SQLite-а: писање велике количине boilerplate кода за креирање табела, недостатак провере SQL упита у фази компајлирања и ручну конверзију Cursor-а у објекте.

Библиотека користи компајлер анотација (kapt или KSP) који генерише имплементацију апстрактних класа RoomDatabase и DAO у фази изградње. Ово гарантује да се синтаксне грешке у SQL-у и неусклађености типова откривају пре покретања апликације, а не у runtime-у након објављивања у Google Play-у.

Према Google I/O 2023, Room се користи у 68% Android апликација које раде са локалним подацима. То је стандард за складиштење података на уређају, препоручен од Google-а за све нове пројекте — уместо застарелих SQLiteOpenHelper и ContentProvider.

Примењујте Room у пројектима где је потребно локално кеширање података са сервера, офлајн режим или складиштење структурираних корисничких података са могућношћу сложених SQL упита.

Room је део Android Jetpack-а и званично је препоручен од Google-а за све нове пројекте који раде са локалним подацима. За разлику од Realm или ObjectBox, Room користи-native SQLite, што гарантује компатибилност са било којим спољним алатима за рад са базом — од DB Browser-а до DataGrip-а. Програмер може отворити .db датотеку апликације и извршавати SQL упите директно, што олакшава отклањање грешака и анализу података у процесу развоја.

Entity и анотације у Room-у

Entity — је класа података анотирана са @Entity, коју Room претвара у табелу базе података. Свако поље класе постаје колона табеле, а свака инстанца — ред. Room користи рефлексију за приступ пољима, па је потребна анотација @PrimaryKey за обавезни идентификатор.

Основне анотације

Анотација @Entity обавештава Room да је класа табела. Параметар tableName поставља име табеле ако се разликује од имена класе. @PrimaryKey дефинише примарни кључ са могућношћу аутоматске генерације кроз 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 поставља име колоне у табели ако се разликује од имена Kotlin поља. @Ignore искључује поље из табеле — неће бити сачувано у базу. @ForeignKey описује спољне кључеве за везе између табела са каскадним операцијама при брисању или ажурирању.

Room подржава угнежђене објекте кроз анотацију @Embedded. Поља угнежђене класе се развијају у колоне родитељске табеле са префиксом за избегавање конфликта имена. На пример, класа Address са пољима city и street, уграђена у User, креира колоне address_city и address_street у табели users, елиминишући потребу за креирањем посебних табела за једноставне вредносне објекте.

Типови конверзије

Room подржава само примитивне типове и њихове омотаче. За складиштење листи, Date или прилагођених типова користи се @TypeConverter — статичке методе конверзије између прилагођеног типа и SQLite примитива, на пример, између List и JSON ниске.

DAO и SQL упити

DAO (Data Access Object) — је интерфејс или апстрактна класа анотирана са @Dao, која садржи методе за приступ подацима. Свака метода је анотирана SQL операцијом: @Insert, @Update, @Delete или @Query са експлицитним SQL упитом.

@Query са провером у фази компајлирања

Анотација @Query прима SQL ниску коју Room проверава у фази компајлирања на исправност синтаксе и усклађеност имена колона са пољима Entity. Room подржава параметризоване упите кроз синтаксу :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 подржава стратегије OnConflictStrategy за обраду конфликата при уметању дуплираних записа. Flow као повратни тип обезбеђује реактивно ажурирање UI-ја при свакој промени података у табели — претплата се аутоматски покреће при сваком INSERT, UPDATE или DELETE.

@Transaction за сложене операције

Анотација @Transaction гарантује атомско извршавање више операција у једном трансакционом блоку. Room закључава базу током извршавања, спречавајући стање трке при конкурентном приступу из више нити.

Database и миграције шеме

RoomDatabase — је апстрактна класа која обједињује Entity и DAO у јединствену тачку приступа бази. Креира се кроз Room.databaseBuilder са навођењем верзије шеме и листе Entity класа. Препоручује се креирање инстанце базе као синглтона кроз lazy делегат ради избегавања вишеструких повезивања.

Миграције

Миграција у Room-у — је класа Migration која описује SQL скрипт за прелазак са старе верзије шеме на нову. Ако миграција није обезбеђена при промени шеме, Room баца IllegalStateException. Ово штити од случајног губитка корисничких података при ажурирању апликације.

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

За развој се може користити fallbackToDestructiveMigration, који брише стару базу и креира нову при неусклађености верзија. Овај режим је намењен само за отклањање грешака — у продукцијским издањима обавезно се пишу миграције.

За тестирање базе података Room пружа посебну класу Room.inMemoryTestBuilder, која креира базу у RAM меморији без чувања на диск. Након завршетка сваког теста, база се аутоматски уништава, што гарантује потпуну изолацију тест сценарија. У комбинацији са библиотеком android-arch-core-testing, програмер може управљати животним циклусом базе и проверавати исправност миграција без потребе за ручним чишћењем стања.

Перформансе Room-а директно зависе од структуре упита и индекса. За анализу спорих упита Room пружа флаг enableQueryCallback, који бележи све SQL упите са временом извршавања. Програмер може користити овај дневник за проналажење упита који трају дуже од 100 милисекунди и оптимизовати их додавањем сложених индекса кроз анотацију @Index у @Entity или преписивањем подупита на директна JOIN спајања коришћењем @Relation.

Room такође подржава шифровање базе података кроз SQLCipher. Повезивање библиотеке net.zetetic:android-database-sqlcipher и коришћење SupportFactory уместо стандардног обезбеђује транспарентно шифровање свих података на диску без промене DAO упита и структуре Entity. Ово је неопходно за апликације које раде са личним подацима корисника и испуњава захтеве GDPR-а и руског закона 152-ФЗ о заштити личних података. Лозинка за шифровање може се чувати у Android Keystore ради заштите од издвајања путем алата на рутованим уређајима.

Room са Kotlin Coroutines и Flow

Room изворно подржава Kotlin Coroutines од верзије 2.1. DAO методе могу бити suspend функције које извршавају упите у позадини без блокирања главне нити. Room аутоматски управља диспечерима, користећи Dispatchers.IO за упите читања и писања.

За реактивне упите Room враћа Flow — хладни ток података који емитује нову вредност при свакој промени погођене табеле. ViewModel се претплаћује на Flow кроз stateIn или collect, обезбеђујући аутоматско ажурирање UI-ја без ручног обавештавања адаптера.

Room такође подржава Paging 3 кроз посебну имплементацију PagingSource која учитава податке по страницама из SQLite-а. Ово је ефикасно за велике листе са хиљадама записа: Paging 3 учитава само редове видљиве на екрану и аутоматски их ажурира при променама у бази.

Користите Paging 3 са Room-ом при приказивању вести, дневника операција или листе производа са могућношћу офлајн приступа и бесконачним скроловањем.

Често постављана питања

По чему се Room разликује од SQLiteOpenHelper-а?

Room аутоматизује креирање табела, конверзију Cursor-а у објекте и проверу SQL-а у фази компајлирања. SQLiteOpenHelper захтева ручно писање шеме, обраду Cursor-а и нема проверу упита пре покретања апликације, што повећава ризик од грешака.

Да ли треба писати миграције за сваку промену шеме?

Да, при промени Entity (додавање/уклањање поља, промена типа) потребна је миграција. Без ње Room баца IllegalStateException при покретању. За развој се може укључити fallbackToDestructiveMigration, али у издању су обавезни исправни скриптови миграције.

Да ли Room подржава релације између табела?

Room подржава @ForeignKey за каскадне операције и @Relation за угнежђене објекте. За сложене JOIN упите користи се анотација @Transaction са @Query, која враћа POJO са угнежђеним ентитетима кроз @Embedded и @Relation.

Може ли се Room користити са Java-ом без Kotlin-а?

Да, Room је потпуно компатибилан са Java-ом. Уместо suspend функција користе се LiveData или RxJava Observable, уместо Flow — LiveData. Room са Java-ом подржава све исте анотације, али захтева више boilerplate кода за асинхроне операције.

Како функционише шифровање Room базе података?

Room подржава шифровање кроз SQLCipher од Zetetic-а. Уместо Room.databaseBuilder користите SupportFactory из библиотеке net.zetetic:android-database-sqlcipher, прослеђујући лозинку за шифровање. Сви подаци на диску биће шифровани транспарентно за DAO упите.

Резиме

  • Room — ORM библиотека Jetpack-а за SQLite са провером SQL-а у фази компајлирања.
  • @Entity описује табелу, @PrimaryKey — идентификатор, @ColumnInfo — име колоне.
  • @Dao садржи методе са @Query, @Insert, @Update и @Delete за приступ подацима.
  • RoomDatabase обједињује Entity и DAO, креира се кроз Room.databaseBuilder.
  • Миграције (Migration) описују SQL скриптове за промену шеме без губитка података.
  • Room изворно подржава Kotlin Coroutines (suspend) и Flow за реактивно ажурирање UI-ја.
  • За велике листе користите Paging 3 са Room-ом кроз PagingSource за странично учитавање.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође