Floor — nedir, Flutter'da SQLite üzerinde ORM

Yazar: IT Sectr Yayınlanma: 2026-03-13 Okuma süresi: 9 dk

Floor — Flutter için ORM (Object-Relational Mapping), SQLite üzerinde tiplendirilmiş bir katman sağlar. Ham SQLite sorgularının aksine Floor, anotasyonlu Dart modellerinden DAO sınıfları üretir. Pub.dev, 2024'e göre, Floor 3500'den fazla Flutter projesinde kullanılmakta ve drift ile hive'ın yanı sıra yerel veri depolama için en popüler üç ORM çözümü arasında yer almaktadır.

Temel Noktalar

  • Floor — anotasyonlar aracılığıyla DAO ve Entity kod üretimi ile SQLite üzerinde ORM
  • Tip güvenliği — sorgular derleme zamanında kontrol edilir, çalışma zamanı SQL hatalarını ortadan kaldırır
  • DAO deseni — Data Access Object SQL sorgularını Dart yöntemlerinde kapsüller
  • Geçişler — SQLite şema sürümlemesi için yerleşik destek
  • Tepkisellik — otomatik UI güncellemesi için Stream aracılığıyla Flow sorguları

Floor nedir?

Floor, SQLite üzerine inşa edilmiş Flutter ve Dart için bir ORM kütüphanesidir. Varlıkları (Entity), Data Access Objects (DAO) ve veritabanını (Database) tanımlamak için anotasyonlar kullanır. Kod üretimi build_runner ve floor_generator aracılığıyla gerçekleştirilir — derleyici DAO uygulamaları ve bir yönetici veritabanı sınıfı oluşturur. Ham sqflite'ın aksine Floor, tür yansıması yoluyla sütunları otomatik olarak Entity alanlarına eşleyerek ResultSet'ten Dart nesnelerine manuel dönüştürme ihtiyacını tamamen ortadan kaldırır.

Floor, Android geliştiricilerine Room'dan tanıdık gelen Repository + DAO desenini izler. Her tablo @Entity anotasyonuna sahip bir Dart sınıfıyla temsil edilir, SQL sorguları @dao anotasyonuna sahip arayüzlerde gruplanır ve veritabanı @Database anotasyonuna sahip soyut bir sınıfta birleştirilir. Bu yaklaşım, veri modelini sorgu mantığından kesin olarak ayırır.

Flutter Pulse (2023)'e göre, yerel veritabanı gerektiren Flutter projelerinin %28'inde Floor seçilmektedir. Seçilmesinin ana nedenleri SQL'e aşinalik (yeni bir sorgu dili öğrenmeye gerek yok) ve derleme zamanı sorgu denetimidir. Ayrıca Floor, özel DSL'lere sahip daha soyut ORM'lere kıyasla hata ayıklaması kolay, okunabilir kod üretir ve bu da ekipteki yeni geliştiriciler için giriş bariyerini düşürür.

Floor Mimarisi

Floor üç katmandan oluşur: Entity (tablo modeli), DAO (sorgu arayüzü) ve Database (giriş noktası). Oluşturucu, alan eşlemesi için _$_Entity uygulamaları ve SQL yürütmesi için _$_Dao oluşturur. Entity veya DAO değiştiğinde, build_runner'ı yeniden başlatmak yeterlidir — kod otomatik olarak güncellenir. Şema sürümleri arasında geçiş için Floor sıralı sürüm numaraları kullanır ve kullanıcı cihazlarında uygulama güncellenirken veri bütünlüğünü garanti eder.

Floor Flutter'da nasıl çalışır?

Floor, platform derlemeleri için sqflite paketi ve masaüstü ile web için sqlite3 aracılığıyla SQLite kullanır. Uygulama başladığında, Floor SQLite dosyasını oluşturur veya açar, geçişleri uygular ve sorguları yürütmek için DAO yöntemlerini hazırlar. Tüm işlemler Future ve Stream aracılığıyla eş zamansız olarak gerçekleştirilir.

Floor'da kod üretimi şu şekilde çalışır: ayrıştırıcı, kaynak dosyalardan anotasyonları okur, modellerin ve sorguların AST'sini (Soyut Sözdizimi Ağacı) oluşturur, ardından _$ ön ekine sahip Dart dosyaları üretir. Oluşturulan kod, ResultSet → Entity eşleyicilerini ve tersini içerir.

Thread güvenliği

Floor, tek bir isolate içinde SQLite ile çalışır. Tüm sorgular eş zamansız olarak yürütülür, ancak eş zamanlı yazmalar SQLite düzeyinde kilitlenir. İşlemler için, bir sorgu grubunun atomikliğini ve hata durumunda geri almayı garanti eden @transaction anotasyonu kullanılır.

Floor vs Drift: Flutter için ORM karşılaştırması

Hem Floor hem de Drift SQLite üzerinde ORM'dir, ancak felsefe olarak farklılık gösterirler. Floor, Android'in Room'una daha yakındır; Drift ise yerleşik Stream API ve SQL dosyaları aracılığıyla sorgu derlemesiyle daha tepkiseldir. Aralarındaki seçim, ekip deneyimine ve gereken tepkiselliğe bağlıdır.

ÖzellikFloorDrift
Sorgu türü@Query'de SQL dizeleriDart yöntemleri + sql dosyaları
Kod üretimifloor_generator (build_runner)drift_dev (build_runner)
TepkisellikDAO'dan StreamYerleşik Stream API + otomatik güncelleme
KarmaşıklıkDüşük (tanıdık SQL)Orta (kendi DSL'si)
GeçişlerManuel SQL betikleriOtomatik + manuel
UyumlulukAndroid, iOS, macOSAndroid, iOS, Web, macOS, Linux

Floor ne zaman seçilmeli

Floor, zaten SQL ve Android Room'a aşina olan ekipler için seçimdir. Geliştiriciler manuel olarak SQL sorguları yazmaya alışıkmış ve SQLite üzerinde minimum bir sarmalayıcı istiyorlarsa — Floor, yeni bir DSL öğrenmeden tiplendirme sağlar. Oluşturulan kod okunabilir ve öngörülebilir olduğu için hata ayıklaması da daha kolaydır.

Drift ne zaman daha iyidir

Drift daha güçlü tepkisellik sunar ve daha fazla platformu destekler. Uygulama UI güncellemeleri için Stream'i aktif olarak kullanıyorsa, JOIN ve alt sorgularla karmaşık sorgular gerektiriyorsa veya web'i hedefliyorsa — Drift tercih edilir. Ancak, kendi DSL'sini öğrenme gerekliliği nedeniyle giriş bariyeri daha yüksektir.

Floor ile kod örnekleri

Floor anotasyonlar etrafında inşa edilmiştir. Aşağıda, bir görev listesi uygulaması için Entity, DAO ve Database'in tam bir örneği verilmiştir. build_runner çalıştırıldıktan sonra, oluşturulan sınıflar kullanıma hazırdır.

Entity ve DAO tanımlama

TaskEntity sınıfı, @Entity anotasyonuyla task tablosuna eşlenir. @primaryKey'e sahip alan birincil anahtar olur. TaskDao arayüzü, tablo işlemleri için yöntemler içerir — her yöntem @Query, @Insert, @Update veya @Delete ile anotasyonlanmıştır.

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

Veritabanı başlatma

@Database anotasyonuna sahip soyut bir sınıf, Entity ve DAO'yu birbirine bağlar. databaseBuilder yöntemi bir veritabanı örneği oluşturur. build çağrıldıktan sonra veritabanı hazırdır: Floor SQLite dosyasını açar, geçişleri uygular ve çalışma için DAO'yu döndürür.

dart
@Database(version: 1, entities: [TaskEntity])
abstract class AppDatabase extends FloorDatabase {
    TaskDao get taskDao;
}

// Kullanım
final database = await $FloorAppDatabase.databaseBuilder('app.db').build();
final taskDao = database.taskDao;
final tasks = await taskDao.getAllTasks();

Stream aracılığıyla tepkisel sorgular

Floor, DAO yöntemlerinden Stream döndürmeyi destekler. Tablodaki herhangi bir değişiklikte, Stream yeni bir liste yayar. Bu, Flutter'daki StreamBuilder ile entegre olur — kayıtlar eklendiğinde, değiştirildiğinde veya silindiğinde UI otomatik olarak güncellenir.

dart
@Query('SELECT * FROM TaskEntity ORDER BY priority DESC')
Stream<List<TaskEntity>> watchAllTasks();

// Flutter widget'nda
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 geçişler ve sürümleme

Floor, @Database anotasyonundaki version parametresi aracılığıyla veritabanı sürümlemesini destekler. Entity değiştiğinde (alan ekleme veya kaldırma), sürümü artırmanız ve bir geçiş eklemeniz gerekir. Geçiş, bir işlem alan ve ALTER TABLE SQL sorgularını yürüten bir Dart işlevidir.

Geçiş örneği

Sürüm 2'de TaskEntity'ye bir dueDate alanı eklediğimizi varsayalım. Geçiş, ALTER TABLE SQL sorgusu aracılığıyla gerçekleştirilir. Bir geçiş belirtilmezse Floor, MigrationStrategy'yi çağırır ve burada bir geri dönüş ayarlayabilirsiniz (örneğin, veri kaybıyla tabloyu yeniden oluşturma).

Floor sorgularını test etme

Floor yerleşik bir mock framework sağlamaz, ancak veritabanı testlerde kolayca değiştirilebilir. Bir inMemoryDatabaseBuilder oluşturun — şemada üretimle aynı olan bellekte bir SQLite veritabanı oluşturur. Her testten sonra, test senaryolarını izole etmek için deleteDatabase aracılığıyla verileri temizleyin.

Floor'da işlemler ve toplu işlemler

Floor, DAO yöntemlerinde @transaction anotasyonu aracılığıyla işlemleri destekler. Bir işlemin içinde, birden çok sorgu, hata durumunda geri alma garantisiyle sıralı olarak yürütülür. List parametresiyle @Insert aracılığıyla toplu ekleme, tek bir çağrıda birden çok kaydı eklemeyi optimize eder — bu, bir döngüde her seferinde bir kaydı eklemekten birkaç kat daha hızlıdır. Toplu işlemler için 100–200 kaydın toplu eklemelerini kullanın: bu, sınırlı kaynaklara sahip mobil cihazlarda yürütme hızı ve RAM tüketimi arasındaki en uygun dengedir.

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

Sıkça Sorulan Sorular

Floor ham sqflite'dan nasıl farklıdır?

sqflite, manuel SQL sorgusu yazma ve ResultSet'i nesnelere eşleme gerektirir. Floor bu kodu otomatik olarak üretir: Entity ve DAO'yu tanımlarsınız ve tiplendirilmiş yöntemler kullanıma hazır Dart nesneleri döndürür. Floor ayrıca anotasyonlar aracılığıyla derleme zamanında SQL sorgularını da kontrol eder.

Floor tablolar arası ilişkileri destekler mi?

Floor, Room gibi ilişkiler için yerleşik anotasyonlara (ForeignKey, @Relation) sahip değildir. İlişkiler, @Query'de manuel SQL JOIN sorguları aracılığıyla uygulanır. Karmaşık ilişkisel şemalar için, yerleşik ilişki desteğine sahip Drift'i düşünün.

Floor SQL sorguları nasıl hata ayıklanır?

Floor, DatabaseBuilder oluştururken bir callback etkinleştirmeye izin verir — bir kaydedici ekleyebileceğiniz sqflite.Database örneği alır. Alternatif olarak, dev modunda şema ve verileri görselleştirmek için floor_doctor kullanın.

Floor web derlemeleri için kullanılabilir mi?

Floor, web ortamında çalışmayan sqflite kullanır. Web için, WASM aracılığıyla sqlite3 ile ayrı bir derleme gerekir. Mevcut sürümde Floor resmi olarak Android, iOS ve macOS'u destekler. Web için sqlite3 adaptörüyle Drift kullanın.

Floor'da sorgu önbellekleme nasıl çalışır?

Floor'un yerleşik önbelleklemesi yoktur — her sorgu SQLite'da yürütülür. Tekrarlanan sorguları önbelleğe almak için, bellekte önbellek (örneğin, dart_cache) ile bir Repository katmanı kullanın. Floor, SQLite ile çalışmak için yalnızca kod üretir, üzerine ek yük eklemez.

Özet

  • Floor — anotasyonlar aracılığıyla Entity, DAO ve Database kod üretimi ile SQLite üzerinde ORM
  • Tip güvenliği — SQL sorguları @Query anotasyonu aracılığıyla derleme zamanında kontrol edilir
  • DAO deseni — SQL sorguları Dart yöntemlerinde kapsüllenir, modeli mantıktan ayırır
  • Geçişler — manuel ALTER TABLE ile Migration aracılığıyla şema sürümlemesi
  • Tepkisellik — değişikliklerde otomatik UI güncellemesi için DAO'dan Stream
  • Sınırlamalar — yerleşik ilişki yok, web derlemelerini desteklemez
  • Öneri — ekibin SQL ve Room yaklaşımına aşina olduğu Flutter projeleri için Floor'u seçin

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun