Floor — bu nədir, Flutter-də SQLite üzərində ORM

Müəllif: IT Sectr Dərc olunub: 2026-03-13 Oxuma vaxtı: 9 dəq

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 — annotasiyalar vasitəsilə DAO və Entity kod generasiyası ilə SQLite üzərində ORM
  • Tip təhlükəsizliyi — sorğular kompilasiya mərhələsində yoxlanılır, SQL runtime səhvləri aradan qaldırılır
  • DAO nümunəsi — Data Access Object SQL sorğularını Dart metodlarında inkapsulə edir
  • Miqrasiyalar — SQLite sxeminin versiyalaşdırılması üçün daxili dəstək
  • Reaktivlik — UI-nin avtomatik yenilənməsi üçün Stream vasitəsilə Flow sorğuları

Floor nədir?

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_runnerfloor_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 arxitekturası

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 Flutter-də necə işləyir?

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 FutureStream 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.

İp təhlükəsizliyi

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.

Floor vs Drift: Flutter üçün ORM müqayisəsi

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ətFloorDrift
Sorğu növü@Query-də SQL sətirləriDart metodları + sql faylları
Kod generasiyasıfloor_generator (build_runner)drift_dev (build_runner)
ReaktivlikDAO-dan StreamDaxili Stream API + auto-updating
MürəkkəblikAşağı (tanış SQL)Orta (öz DSL)
MiqrasiyalarƏl ilə SQL skriptləriAvtomatik + əl ilə
UyğunluqAndroid, iOS, macOSAndroid, iOS, Web, macOS, Linux

Floor nə vaxt seçilməlidir

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 nə vaxt daha yaxşıdır

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 ilə kod nümunələri

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.

Entity və DAO təyini

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.

dart
@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);
}

Verilənlər bazasının işə salınması

@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.

dart
@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();

Stream vasitəsilə reaktiv sorğular

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.

dart
@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-da miqrasiyalar və versiyalaşdırma

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.

Miqrasiya nümunəsi

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 sorğularının test edilməsi

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-da tranzaksiyalar və toplu əməliyyatlar

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 parametri ilə toplu daxil etmə bir çağırışda çoxlu qeydin daxil edilməsini optimallaşdırır — bu, dövrədə tək-tək daxil etməkdən bir neçə dəfə sürətlidir. Kütləvi əməliyyatlar üçün 100–200 qeyd olmaqla toplu daxil etmədən istifadə edin: bu, məhdud resurslu mobil cihazlarda icra sürəti və RAM istehlakı arasında optimal balansdır.

dart
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

Floor xam sqflite-dən nə ilə fərqlənir?

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 cədvəllər arasında əlaqələri dəstəkləyirmi?

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 SQL sorğularını necə debug etmək olar?

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 qurğusu üçün istifadə edilə bilərmi?

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-da sorğu keşləmə necə işləyir?

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ə

  • Floor — annotasiyalar vasitəsilə Entity, DAO və Database kod generasiyası ilə SQLite üzərində ORM
  • Tip təhlükəsizliyi — SQL sorğuları @Query annotasiyası vasitəsilə kompilasiya mərhələsində yoxlanılır
  • DAO nümunəsi — SQL sorğuları Dart metodlarında inkapsulə edilir, model və məntiqi ayırır
  • Miqrasiyalar — əl ilə ALTER TABLE ilə Migration vasitəsilə sxem versiyalaşdırılması
  • Reaktivlik — dəyişikliklər zamanı UI-nin avtomatik yenilənməsi üçün DAO-dan Stream
  • Məhdudiyyətlər — daxili əlaqələr yoxdur, web qurğusunu dəstəkləmir
  • Tövsiyə — komandanın SQL və Room yanaşmasını bildiyi Flutter layihələri üçün Floor seçin

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.

Layihəni müzakirə et

Həm də oxuyun