Room — Jetpack-in tərkib hissəsi olan, Android-də SQLite ilə iş üçün kitabxanadır. O, xam SQLite üzərində abstraksiya qatı təmin edir, cədvəllərin yaradılmasını, sorğuların icrasını və məlumatların Kotlin və Java obyektlərinə çevrilməsini avtomatlaşdırır. Android Developers məlumatına görə, Room SQL sorğularını qurma mərhələsində kompilyasiya edir, sintaksisin düzgünlüyünü və Entity ilə cədvəllər arasındakı əlaqələri yoxlayır.
Əsas məqamlar
Room — Android Jetpack-in tərkibinə daxil olan, SQLite üçün obyekt-relational xəritələmə təmin edən davamlılıq kitabxanasıdır. Room xam SQLite-in üç əsas problemini həll edir: cədvəllərin yaradılması üçün çoxlu boilerplate kod yazılması, SQL sorğularının kompilyasiya mərhələsində yoxlanılmaması və Cursor-un əl ilə obyektlərə çevrilməsi.
Kitabxana annotasiya kompilyatorundan (kapt və ya KSP) istifadə edir, o, qurma mərhələsində RoomDatabase və DAO abstrakt siniflərinin implementasiyasını yaradır. Bu, SQL-də sintaksis səhvlərinin və tip uyğunsuzluqlarının tətbiq işə salınmazdan əvvəl — Google Play-də dərc edildikdən sonra runtime-da yox, əvvəlcədən aşkarlanmasını təmin edir.
Google I/O 2023 məlumatına görə, Room lokal məlumatlarla işləyən Android tətbiqlərinin 68%-də istifadə olunur. Bu, Google tərəfindən bütün yeni layihələr üçün tövsiyə edilən cihazda məlumat saxlama standartıdır — köhnəlmiş SQLiteOpenHelper və ContentProvider əvəzinə.
Room-u serverdən məlumatların lokal keşləşdirilməsi, oflayn rejim və ya mürəkkəb SQL sorğuları imkanı ilə strukturlaşdırılmış istifadəçi məlumatlarının saxlanması tələb olunan layihələrdə tətbiq edin.
Room Android Jetpack-in bir hissəsidir və Google tərəfindən lokal məlumatlarla işləyən bütün yeni layihələr üçün rəsmi olaraq tövsiyə olunur. Realm və ya ObjectBox-dan fərqli olaraq, Room yerli SQLite istifadə edir, bu da DB Browser-dən DataGrip-ə qədər hər hansı üçüncü tərəf alətləri ilə uyğunluğu təmin edir. Tərtibatçı tətbiqin .db faylını aça və birbaşa SQL sorğuları icra edə bilər, bu da inkişaf prosesində məlumatların debug edilməsini və təhlilini asanlaşdırır.
Entity — @Entity ilə annotasiya olunmuş məlumat sinfidir, Room onu verilənlər bazası cədvəlinə çevirir. Sinfin hər bir sahəsi cədvəlin sütununa, hər bir nümunə isə sətrə çevrilir. Room sahələrə daxil olmaq üçün refeksiyadan istifadə edir, buna görə də məcburi identifikator üçün @PrimaryKey annotasiyası tələb olunur.
@Entity annotasiyası Room-a sinfin cədvəl olduğunu bildirir. tableName parametri cədvəlin adını təyin edir, əgər o sinfin adından fərqlidirsə. @PrimaryKey autoGenerate = true vasitəsilə avto-generasiya imkanı ilə əsas açarı müəyyən edir.
@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 cədvəldə sütunun adını təyin edir, əgər o Kotlin sahəsinin adından fərqlidirsə. @Ignore sahəni cədvəldən xaric edir — o verilənlər bazasına yazılmayacaq. @ForeignKey silmə və ya yeniləmə zamanı kaskad əməliyyatları ilə cədvəllər arasında xarici açarları təsvir edir.
Room @Embedded annotasiyası vasitəsilə iç-içə obyektləri dəstəkləyir. İç-içə sinfin sahələri ad konfliktindən qaçmaq üçün prefiks ilə valideyn cədvəlinin sütunlarına açılır. Məsələn, city və street sahələri olan Address sinfi, User-a daxil edildikdə, users cədvəlində address_city və address_street sütunlarını yaradır və sadə value-obyektlər üçün ayrıca cədvəllər yaratmaq ehtiyacını aradan qaldırır.
Room yalnız primitiv növləri və onların qablaşdırmalarını dəstəkləyir. Siyahıların, Date-in və ya fərdi növlərin saxlanması üçün @TypeConverter istifadə olunur — fərdi növ ilə SQLite primitivi arasında statik çevirmə metodları, məsələn, List ilə JSON sətri arasında.
DAO (Data Access Object) — @Dao ilə annotasiya olunmuş, məlumatlara giriş metodlarını ehtiva edən interfeys və ya abstrakt sinifdir. Hər bir metod SQL əməliyyatı ilə annotasiya olunur: @Insert, @Update, @Delete və ya aşkar SQL sorğusu ilə @Query.
@Query annotasiyası Room tərəfindən kompilyasiya mərhələsində sintaksisin düzgünlüyü və sütun adlarının Entity sahələrinə uyğunluğu baxımından yoxlanılan SQL sətrini qəbul edir. Room :paramName sintaksisi vasitəsilə parametrləşdirilmiş sorğuları dəstəkləyir.
@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 təkrarlanan qeydlərin daxil edilməsi zamanı konfliktlərin idarə edilməsi üçün OnConflictStrategy strategiyalarını dəstəkləyir. Qaytarılan tip kimi Flow cədvəldəki hər bir məlumat dəyişikliyində UI-nin reaktiv yenilənməsini təmin edir — abunə hər INSERT, UPDATE və ya DELETE zamanı avtomatik yenidən başladılır.
@Transaction annotasiyası bir tranzaksiya blokunda bir neçə əməliyyatın atomik icrasını təmin edir. Room icra müddətində verilənlər bazasını bloklayır, çoxlu iplərdən eyni vaxtda giriş zamanı yarış vəziyyətinin qarşısını alır.
RoomDatabase — Entity və DAO-nu verilənlər bazasına vahid giriş nöqtəsində birləşdirən abstrakt sinifdir. O, Room.databaseBuilder vasitəsilə sxem versiyası və Entity siniflərinin siyahısı göstərilməklə yaradılır. Verilənlər bazası nümunəsinin çoxsaylı qoşulmaların qarşısını almaq üçün lazy-deleqat vasitəsilə sinqlton kimi yaradılması tövsiyə olunur.
Miqrasiya Room-da — köhnə sxem versiyasından yenisinə keçid üçün SQL skriptini təsvir edən Migration sinfidir. Sxem dəyişikliyi zamanı miqrasiya təmin edilməzsə, Room IllegalStateException atır. Bu, tətbiq yenilənməsi zamanı istifadəçi məlumatlarının təsadüfi itkisindən qoruyur.
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()
İnkişaf üçün fallbackToDestructiveMigration istifadə edilə bilər, o versiyalar uyğun gəlmədikdə köhnə verilənlər bazasını silir və yenisini yaradır. Bu rejim yalnız debug üçün nəzərdə tutulub — istehsal buraxılışlarında mütləq miqrasiyalar yazılır.
Verilənlər bazasının test edilməsi üçün Room xüsusi Room.inMemoryTestBuilder sinfini təqdim edir, o disklə yazmadan operativ yaddaşda verilənlər bazası yaradır. Hər test bitdikdən sonra verilənlər bazası avtomatik məhv edilir, bu da test ssenarilərinin tam izolyasiyasını təmin edir. android-arch-core-testing kitabxanası ilə birlikdə tərtibatçı verilənlər bazasının həyat dövrünü idarə edə və vəziyyəti əl ilə təmizləmədən miqrasiyaların düzgünlüyünü yoxlaya bilər.
Room-un performansı birbaşa sorğuların və indekslərin strukturundan asılıdır. Yavaş sorğuların təhlili üçün Room enableQueryCallback bayrağını təqdim edir, o bütün SQL sorğularını icra müddəti ilə birlikdə loglayır. Tərtibatçı bu logdan 100 millisaniyədən uzun çəkən sorğuları tapmaq və onları @Entity-də @Index annotasiyası ilə mürəkkəb indekslər əlavə etməklə və ya @Relation istifadə edərək alt sorğuları birbaşa JOIN birləşmələrinə yenidən yazmaqla optimallaşdıra bilər.
Room həmçinin SQLCipher vasitəsilə verilənlər bazasının şifrələnməsini dəstəkləyir. net.zetetic:android-database-sqlcipher kitabxanasının qoşulması və standart əvəzinə SupportFactory istifadə edilməsi DAO sorğularını və Entity strukturunu dəyişmədən diskdəki bütün məlumatların şəffaf şifrələnməsini təmin edir. Bu, istifadəçilərin şəxsi məlumatları ilə işləyən tətbiqlər üçün zəruridir və GDPR və Rusiyanın 152-FZ şəxsi məlumatların qorunması haqqında qanununun tələblərinə cavab verir. Şifrələmə parolu root edilmiş cihazlarda alətlər vasitəsilə çıxarılmasından qorunmaq üçün Android Keystore-da saxlanıla bilər.
Room 2.1 versiyasından etibarən Kotlin Coroutines-i yerli olaraq dəstəkləyir. DAO metodları əsas thread-i bloklamadan fon thread-də sorğuları icra edən suspend funksiyaları ola bilər. Room oxu və yazı sorğuları üçün Dispatchers.IO istifadə edərək dispetçerləri avtomatik idarə edir.
Reaktiv sorğular üçün Room Flow qaytarır — təsirlənmiş cədvəldə hər dəyişiklikdə yeni dəyər göndərən soyuq məlumat axını. ViewModel stateIn və ya collect vasitəsilə Flow-a abunə olur, adapteri əl ilə xəbərdar etmədən UI-nin avtomatik yenilənməsini təmin edir.
Room həmçinin Paging 3-ü SQLite-dən səhifə-səhifə məlumat yükləyən xüsusi PagingSource implementasiyası vasitəsilə dəstəkləyir. Bu, minlərlə qeydi olan böyük siyahılar üçün effektivdir: Paging 3 yalnız ekranda görünən sətirləri yükləyir və verilənlər bazasında dəyişikliklər olduqda onları avtomatik yeniləyir.
Paging 3-ü Room ilə xəbər lentinin, əməliyyat jurnalının və ya oflayn giriş və sonsuz sürüşdürmə imkanı ilə məhsul siyahısının göstərilməsi zamanı istifadə edin.
Tez-tez verilən suallar
Room cədvəllərin yaradılmasını, Cursor-un obyektlərə çevrilməsini və SQL-in kompilyasiya mərhələsində yoxlanılmasını avtomatlaşdırır. SQLiteOpenHelper sxemi əl ilə yazmağı, Cursor-u emal etməyi tələb edir və tətbiq işə salınmazdan əvvəl sorğuları yoxlamır, bu da səhv riskini artırır.
Bəli, Entity dəyişikliyi zamanı (sahənin əlavə edilməsi/silinməsi, tipin dəyişdirilməsi) miqrasiya tələb olunur. Olmadan Room işə salındıqda IllegalStateException atır. İnkişaf üçün fallbackToDestructiveMigration aktivləşdirilə bilər, lakin buraxılışda düzgün miqrasiya skriptləri məcburidir.
Room kaskad əməliyyatları üçün @ForeignKey və iç-içə obyektlər üçün @Relation dəstəkləyir. Mürəkkəb JOIN sorğuları üçün @Transaction annotasiyası @Embedded və @Relation vasitəsilə iç-içə varlıqlarla POJO qaytaran @Query ilə istifadə olunur.
Bəli, Room Java ilə tam uyğundur. Suspend funksiyaları əvəzinə LiveData və ya RxJava Observable, Flow əvəzinə LiveData istifadə olunur. Room Java ilə eyni annotasiyaların hamısını dəstəkləyir, lakin asinxron əməliyyatlar üçün daha çox boilerplate kod tələb edir.
Room Zetetic-dən SQLCipher vasitəsilə şifrələməni dəstəkləyir. Room.databaseBuilder əvəzinə net.zetetic:android-database-sqlcipher kitabxanasından SupportFactory istifadə edin, şifrələmə parolunu ötürün. Diskdəki bütün məlumatlar DAO sorğuları üçün şəffaf şəkildə şifrələnəcək.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun