Floor — Flutter üçün SQLite üzərində tipli təbəqə təmin edən ORM (Object-Relational Mapping). Xam SQLite sorğularından fərqli olaraq, Floor annotasiya edilmiş Dart modellərindən DAO sinifləri yaradır. Pub.dev, 2024 məlumatına görə, Floor 3500-dən çox Flutter layihəsində istifadə olunur və drift və hive ilə birlikdə yerli məlumat saxlama üçün ən populyar ORM həllərindən biridir.
Əsas məqamlar
Floor — SQLite əsasında qurulmuş Flutter və Dart üçün ORM kitabxanasıdır. O, varlıqları (Entity), Data Access Object (DAO) və verilənlər bazasını (Database) təsvir etmək üçün annotasiyalardan istifadə edir. Kod generasiyası build_runner və floor_generator vasitəsilə həyata keçirilir — kompilyator DAO implementasiyaları və idarəedici verilənlər bazası sinfi yaradır. Xam sqflite-dən fərqli olaraq, Floor ResultSet-in Dart obyektlərinə əl ilə çevrilməsi ehtiyacını tamamilə aradan qaldırır, avtomatik olaraq sütunları Entity sahələrinə tip əks etdirməsi vasitəsilə map edir.
Floor Android proqramçılarına Room-dan tanış olan Repository + DAO nümunəsini izləyir. Hər bir cədvəl @Entity annotasiyası ilə Dart sinfi ilə təmsil olunur, SQL sorğuları @dao annotasiyası ilə interfeyslərdə qruplaşdırılır və verilənlər bazası @Database ilə abstrakt sinifdə yığılır. Bu yanaşma məlumat modelini və sorğu məntiqini ciddi şəkildə ayırır.
Flutter Pulse (2023) məlumatına görə, Floor yerli verilənlər bazası tələb edən Flutter layihələrinin 28%-də seçilir. Əsas seçim səbəbləri — SQL biliyi (yeni sorğu dili öyrənmək lazım deyil) və sorğuların kompilasiya mərhələsində yoxlanılmasıdır. Bundan əlavə, Floor oxunaqlı kod yaradır ki, bu da fərdi DSL ilə daha abstrakt ORM-lərdən fərqli olaraq asanlıqla debug edilir və komandada yeni proqramçılar üçün giriş həddini aşağı salır.
Floor üç təbəqədən ibarətdir: Entity (cədvəl modeli), DAO (sorğu interfeysi) və Database (giriş nöqtəsi). Generator sahələrin map edilməsi üçün _$_Entity və SQL-in icrası üçün _$_Dao implementasiyalarını yaradır. Entity və ya DAO dəyişdirildikdə, build_runner-ı yenidən işə salmaq kifayətdir — kod avtomatik yenilənəcək. Sxem versiyaları arasında miqrasiya üçün Floor ardıcıl versiya nömrələrindən istifadə edir ki, bu da istifadəçi cihazlarında tətbiq yeniləməsi zamanı məlumat bütövlüyünü təmin edir.
Floor platforma qurğuları üçün sqflite paketi, desktop və web üçün isə sqlite3 vasitəsilə SQLite-dən istifadə edir. Tətbiq işə salındıqda Floor SQLite faylını yaradır və ya açır, miqrasiyaları tətbiq edir və sorğuların icrası üçün DAO metodlarını hazırlayır. Bütün əməliyyatlar Future və Stream vasitəsilə asinxron rejimdə yerinə yetirilir.
Floor-da kod generasiyası aşağıdakı prinsiplə işləyir: parser mənbə kodlarından annotasiyaları oxuyur, modellərin və sorğuların AST (Abstract Syntax Tree) ağacını yaradır, sonra _$ prefiksi ilə Dart faylları yaradır. Yaradılan kod ResultSet → Entity və əksinə mapperləri ehtiva edir.
Floor bir izolyatda SQLite ilə işləyir. Bütün sorğular asinxron icra olunur, lakin paralel yazmalar SQLite səviyyəsində bloklanır. Tranzaksiyalar üçün @transaction annotasiyası istifadə olunur ki, bu da sorğular qrupunun atomarlığını və xəta zamanı geri qaytarılmasını təmin edir.
Həm Floor, həm də Drift — SQLite üzərində ORM-lərdir, lakin fəlsəfələri fərqlidir. Floor Android-dəki Room-a daha yaxındır, Drift isə daxili Stream API və SQL faylları vasitəsilə sorğu kompilasiyası ilə daha reaktivdir. Onlar arasında seçim komandanın təcrübəsindən və tələb olunan reaktivlikdən asılıdır.
| Xüsusiyyət | Floor | Drift |
|---|---|---|
| Sorğu növü | @Query-də SQL sətirləri | Dart metodları + sql faylları |
| Kod generasiyası | floor_generator (build_runner) | drift_dev (build_runner) |
| Reaktivlik | DAO-dan Stream | Daxili Stream API + auto-updating |
| Mürəkkəblik | Aşağı (tanış SQL) | Orta (öz DSL) |
| Miqrasiyalar | Əl ilə SQL skriptləri | Avtomatik + əl ilə |
| Uyğunluq | Android, iOS, macOS | Android, iOS, Web, macOS, Linux |
Floor — SQL və Android Room-u artıq bilən komandaların seçimidir. Proqramçılar SQL sorğularını əl ilə yazmağa öyrəşiblərsə və SQLite üzərində minimal örtük istəyirlərsə — Floor yeni DSL öyrənmədən tipizasiya təmin edir. O, həmçinin debug etmək daha asandır, çünki yaradılan kod oxunaqlı və proqnozlaşdırıla biləndir.
Drift daha güclü reaktivlik verir və daha çox platformanı dəstəkləyir. Tətbiq UI yeniləməsi üçün Stream-dən fəal istifadə edirsə, JOIN və alt sorğularla mürəkkəb sorğular tələb edirsə və ya web altında qurulursa — Drift üstünlük təşkil edir. Bununla birlikdə, öz DSL-ni öyrənmək zərurəti səbəbindən giriş həddi daha yüksəkdir.
Floor annotasiyalar ətrafında qurulur. Aşağıda tapşırıq siyahısı tətbiqi üçün Entity, DAO və Database-in tam nümunəsi verilmişdir. build_runner işə salındıqdan sonra yaradılan siniflər istifadəyə hazırdır.
TaskEntity sinfi @Entity annotasiyası ilə task cədvəlinə map olunur. @primaryKey sahəsi əsas açar olur. TaskDao interfeysi cədvəl əməliyyatları üçün metodları ehtiva edir — hər bir metod @Query, @Insert, @Update və ya @Delete ilə annotasiya olunur.
@entity
class TaskEntity {
@PrimaryKey(autoGenerate: true)
final int id;
final String title;
final bool isCompleted;
final int priority;
TaskEntity({this.id, required this.title,
this.isCompleted = false, this.priority = 0});
}
@dao
abstract class TaskDao {
@Query('SELECT * FROM TaskEntity ORDER BY priority DESC')
Future<List<TaskEntity>> getAllTasks();
@Insert
Future<int> insertTask(TaskEntity task);
@Update
Future<void> updateTask(TaskEntity task);
@Query('SELECT * FROM TaskEntity WHERE isCompleted = :status')
Stream<List<TaskEntity>> watchTasks(bool status);
}
@Database annotasiyası ilə abstrakt sinif Entity və DAO-nu birləşdirir. databaseBuilder metodu verilənlər bazasının nümunəsini yaradır. Build çağırıldıqdan sonra baza hazırdır: Floor SQLite faylını açır, miqrasiyaları tətbiq edir və iş üçün DAO qaytarır.
@Database(version: 1, entities: [TaskEntity])
abstract class AppDatabase extends FloorDatabase {
TaskDao get taskDao;
}
// İstifadə
final database = await $FloorAppDatabase.databaseBuilder('app.db').build();
final taskDao = database.taskDao;
final tasks = await taskDao.getAllTasks();
Floor DAO metodlarından Stream qaytarılmasını dəstəkləyir. Cədvəldə hər hansı dəyişiklik olduqda Stream yeni siyahı göndərir. Bu, Flutter-də StreamBuilder ilə inteqrasiya olunur — qeydlər əlavə edildikdə, dəyişdirildikdə və ya silindikdə UI avtomatik yenilənir.
@Query('SELECT * FROM TaskEntity ORDER BY priority DESC')
Stream<List<TaskEntity>> watchAllTasks();
// Flutter vidjetində
StreamBuilder<List<TaskEntity>>(
stream: taskDao.watchAllTasks(),
builder: (context, snapshot) {
final tasks = snapshot.data ?? [];
return ListView.builder(
itemCount: tasks.length,
itemBuilder: (_, i) => TaskTile(tasks[i]),
);
},
)
Floor @Database annotasiyasında version parametri vasitəsilə verilənlər bazasının versiyalaşdırılmasını dəstəkləyir. Entity dəyişdirildikdə (sahələr əlavə edildikdə və ya silindikdə) versiyanı artırmaq və miqrasiya əlavə etmək lazımdır. Miqrasiya — tranzaksiya alan və ALTER TABLE SQL sorğularını icra edən Dart funksiyasıdır.
Tutaq ki, 2-ci versiyada TaskEntity-ə dueDate sahəsi əlavə etdik. Miqrasiya ALTER TABLE SQL sorğusu ilə icra olunur. Miqrasiya göstərilməyibsə, Floor MigrationStrategy çağırır, burada fallback təyin edilə bilər (məsələn, məlumat itkisi ilə cədvəlin yenidən yaradılması).
Floor daxili mock framework təmin etmir, lakin verilənlər bazası testlərdə asanlıqla əvəz edilə bilər. inMemoryDatabaseBuilder yaradın — o, sxemə görə istehsal bazası ilə eyni olan yaddaş daxilində SQLite bazası yaradır. Hər testdən sonra test ssenarilərinin izolyasiyası üçün məlumatları deleteDatabase vasitəsilə təmizləyin.
Floor DAO metodunda @transaction annotasiyası vasitəsilə tranzaksiyaları dəstəkləyir. Tranzaksiya daxilində bir neçə sorğu ardıcıl olaraq xəta zamanı geri qaytarılma zəmanəti ilə icra olunur. @Insert ilə List
final migration1to2 = Migration(1, 2, (database) async {
await database.execute(
'ALTER TABLE TaskEntity ADD COLUMN dueDate TEXT'
);
});
final database = await $FloorAppDatabase.databaseBuilder('app.db')
.addMigrations([migration1to2])
.build();
Tez-tez verilən suallar
sqflite SQL sorğularının əl ilə yazılmasını və ResultSet-in obyektlərə map edilməsini tələb edir. Floor bu kodu avtomatik yaradır: siz Entity və DAO-nu təsvir edirsiniz, tipləşdirilmiş metodlar isə hazır Dart obyektlərini qaytarır. Floor həmçinin annotasiyalar vasitəsilə SQL sorğularını kompilasiya mərhələsində yoxlayır.
Floor-da Room kimi əlaqələr üçün daxili annotasiyalar (ForeignKey, @Relation) yoxdur. Əlaqələr @Query-də əl ilə SQL JOIN sorğuları vasitəsilə həyata keçirilir. Mürəkkəb relyasiya sxemləri üçün əlaqələr üçün daxili dəstəyi olan Drift-i nəzərdən keçirmək daha yaxşıdır.
Floor DatabaseBuilder yaradılarkən callback geri çağırışını aktivləşdirməyə imkan verir — ona sqflite.Database nümunəsi ötürülür, ona logger bağlamaq olar. Alternativ olaraq, dev rejimində sxem və məlumatların vizuallaşdırılması üçün floor_doctor istifadə edin.
Floor web mühitində işləməyən sqflite-dən istifadə edir. Web üçün WASM vasitəsilə sqlite3 ilə ayrıca qurğu tələb olunacaq. Cari versiyada Floor rəsmi olaraq Android, iOS və macOS-ı dəstəkləyir. Web üçün sqlite3 adapteri ilə Drift-dən istifadə edin.
Floor-un daxili keşləməsi yoxdur — hər sorğu SQLite-ə icra olunur. Təkrarlanan sorğuların keşlənməsi üçün yaddaşdaxili keşlə Repository təbəqəsindən istifadə edin (məsələn, dart_cache). Floor yalnız SQLite ilə iş üçün kod yaradır, onun üzərinə əlavələr qoymur.
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