Floor — ORM (Object-Relational Mapping) Flutterhez, amely tipizált réteget biztosít az SQLite fölött. Ellentétben a nyers SQLite lekérdezésekkel, a Floor DAO osztályokat generál annotált Dart modellekből. A Pub.dev, 2024 adatai szerint a Floor-t több mint 3500 Flutter projektben használják, és a három legnépszerűbb ORM megoldás közé tartozik a helyi adattároláshoz a drift és a hive mellett.
Főbb pontok
Floor — egy ORM könyvtár Flutter és Dart számára, az SQLite alapjaira építve. Annotációkat használ entitások (Entity), Data Access Object (DAO) és adatbázis (Database) leírásához. A kódgenerálás a build_runner és floor_generator segítségével történik — a fordító létrehozza a DAO implementációkat és az adatbázis-kezelő osztályt. Ellentétben a nyers sqflite-tal, a Floor teljesen kiküszöböli a ResultSet manuális Dart objektumokká alakításának szükségességét, automatikusan leképezve az oszlopokat az Entity mezőire típusreflexió segítségével.
A Floor a Repository + DAO mintát követi, amely ismerős az Android fejlesztők számára a Room-ból. Minden táblát egy Dart osztály képvisel a @Entity annotációval, az SQL lekérdezések a @dao annotációval ellátott interfészekbe vannak csoportosítva, és az adatbázis egy @Database annotációval ellátott absztrakt osztályban van összeállítva. Ez a megközelítés szigorúan elválasztja az adatmodellt és a lekérdezési logikát.
A Flutter Pulse (2023) szerint a Floor-t a Flutter projektek 28%-ában választják, ahol helyi adatbázisra van szükség. A választás fő okai — az SQL ismerete (nem kell új lekérdezési nyelvet tanulni) és a lekérdezések fordítási időben történő ellenőrzése. Ezenkívül a Floor olvasható kódot generál, amely könnyen debugolható, ellentétben az elvontabb, egyedi DSL-lel rendelkező ORM-ekkel, ami csökkenti a belépési küszöböt az új fejlesztők számára a csapatban.
Floor három rétegből áll: Entity (táblamodell), DAO (lekérdezési interfész) és Database (belépési pont). A generátor létrehozza a _$_Entity implementációkat a mezők leképezéséhez és a _$_Dao implementációkat az SQL végrehajtásához. Az Entity vagy DAO megváltoztatásakor elegendő újraindítani a build_runner-t — a kód automatikusan frissül. A séma verziói közötti migrációhoz a Floor szekvenciális verziószámokat használ, ami garantálja az adatok integritását az alkalmazás frissítésekor a felhasználók eszközein.
Floor az SQLite-ot használja a sqflite csomagon keresztül platform build-ekhez és a sqlite3-at asztali és webes környezethez. Az alkalmazás indításakor a Floor létrehozza vagy megnyitja az SQLite fájlt, alkalmazza a migrációkat és előkészíti a DAO metódusokat a lekérdezések végrehajtásához. Minden művelet aszinkron módon történik a Future és Stream segítségével.
A kódgenerálás a Floor-ban a következő elv szerint működik: az elemző beolvassa az annotációkat a forráskódból, létrehozza a modellek és lekérdezések AST (Abstract Syntax Tree) fáját, majd _$ előtaggal ellátott Dart fájlokat generál. A generált kód tartalmazza a ResultSet → Entity és visszirányú leképezőket.
Floor egy izolátumban dolgozik az SQLite-tal. Minden lekérdezés aszinkron módon hajtódik végre, de a párhuzamos írások blokkolva vannak az SQLite szintjén. Tranzakciókhoz a @transaction annotációt használják, amely garantálja a lekérdezési csoport atomitását és visszagörgetést hiba esetén.
Mind a Floor, mind a Drift — ORM az SQLite fölött, de filozófiájukban különböznek. A Floor közelebb áll az Android-beli Room-hoz, a Drift — reaktívabb a beépített Stream API-val és a lekérdezések SQL fájlokon keresztüli fordításával. A köztük lévő választás a csapat tapasztalatától és a szükséges reaktivitástól függ.
| Jellemző | Floor | Drift |
|---|---|---|
| Lekérdezés típusa | SQL sztringek a @Query-ben | Dart metódusok + sql fájlok |
| Kódgenerálás | floor_generator (build_runner) | drift_dev (build_runner) |
| Reaktivitás | Stream a DAO-ból | Beépített Stream API + automatikus frissítés |
| Komplexitás | Alacsony (ismert SQL) | Közepes (saját DSL) |
| Migrációk | Kézi SQL szkriptek | Automatikus + kézi |
| Kompatibilitás | Android, iOS, macOS | Android, iOS, Web, macOS, Linux |
Floor — azon csapatok választása, akik már ismerik az SQL-t és az Android Room-ot. Ha a fejlesztők hozzászoktak az SQL lekérdezések kézi írásához és minimális burkolót szeretnének az SQLite fölé — a Floor tipizálást biztosít anélkül, hogy új DSL-t kellene tanulni. Emellett könnyebben debugolható, mivel a generált kód olvasható és kiszámítható.
Drift erősebb reaktivitást nyújt és több platformot támogat. Ha az alkalmazás aktívan használja a Stream-et az UI frissítéséhez, összetett lekérdezéseket igényel JOIN-nal és allekérdezésekkel, vagy webre épül — a Drift előnyösebb. Azonban a belépési küszöbe magasabb a saját DSL megtanulásának szükségessége miatt.
Floor az annotációk köré épül. Alább egy teljes példa Entity, DAO és Database számára egy feladatlista alkalmazáshoz. A build_runner futtatása után a generált osztályok használatra készek.
A TaskEntity osztály a @Entity annotációval a task táblára képeződik le. A @primaryKey mező elsődleges kulccsá válik. A TaskDao interfész metódusokat tartalmaz a tábla műveleteihez — minden metódus @Query, @Insert, @Update vagy @Delete annotációval van ellátva.
@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);
}
A @Database annotációval ellátott absztrakt osztály összeköti az Entity-t és a DAO-t. A databaseBuilder metódus létrehozza az adatbázis példányát. A build meghívása után az adatbázis készen áll: a Floor megnyitja az SQLite fájlt, alkalmazza a migrációkat és visszaadja a DAO-t a munkához.
@Database(version: 1, entities: [TaskEntity])
abstract class AppDatabase extends FloorDatabase {
TaskDao get taskDao;
}
// Használat
final database = await $FloorAppDatabase.databaseBuilder('app.db').build();
final taskDao = database.taskDao;
final tasks = await taskDao.getAllTasks();
Floor támogatja a Stream visszaadását a DAO metódusokból. Bármilyen változáskor a táblában a Stream új listát bocsát ki. Ez integrálódik a StreamBuilder-rel Flutterben — az UI automatikusan frissül rekordok hozzáadásakor, módosításakor vagy törlésekor.
@Query('SELECT * FROM TaskEntity ORDER BY priority DESC')
Stream<List<TaskEntity>> watchAllTasks();
// Flutter widgetben
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 támogatja az adatbázis verziókezelését a @Database annotáció version paraméterén keresztül. Az Entity megváltoztatásakor (mezők hozzáadásakor vagy eltávolításakor) növelni kell a verziót és hozzáadni egy migrációt. A migráció egy Dart függvény, amely tranzakciót kap és ALTER TABLE SQL lekérdezéseket hajt végre.
Tegyük fel, hogy a 2-es verzióban hozzáadtuk a dueDate mezőt a TaskEntity-hez. A migráció az ALTER TABLE SQL lekérdezéssel történik. Ha a migráció nincs megadva, a Floor meghívja a MigrationStrategy-t, ahol fallback állítható be (például a tábla újra létrehozása adatvesztéssel).
Floor nem biztosít beépített mock keretrendszert, de az adatbázis könnyen helyettesíthető tesztekben. Hozzon létre inMemoryDatabaseBuilder-t — ez egy SQLite adatbázist hoz létre a memóriában, amely sémájában megegyezik a production-nel. Minden teszt után törölje az adatokat a deleteDatabase segítségével a teszt forgatókönyvek elkülönítéséhez.
Floor támogatja a tranzakciókat a @transaction annotáción keresztül a DAO metóduson. A tranzakción belül több lekérdezés szekvenciálisan hajtódik végre a hiba esetén történő visszagörgetés garanciájával. A batch beszúrás a @Insert segítségével a List<T> paraméterrel optimalizálja több rekord egyetlen hívásban történő beszúrását — ez többször gyorsabb, mint a rekordok egyenkénti beszúrása ciklusban. Tömeges műveletekhez használjon 100–200 rekordos batch beszúrást: ez az optimális egyensúly a végrehajtási sebesség és a RAM fogyasztás között a korlátozott erőforrásokkal rendelkező mobileszközökön.
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();
Gyakran Ismételt Kérdések
sqflite az SQL lekérdezések kézi írását és a ResultSet objektumokká alakítását igényli. A Floor ezt a kódot automatikusan generálja: leírja az Entity-t és a DAO-t, a tipizált metódusok pedig kész Dart objektumokat adnak vissza. A Floor az SQL lekérdezéseket is ellenőrzi fordítási időben az annotációkon keresztül.
Floor nem rendelkezik beépített annotációkkal a kapcsolatokhoz (ForeignKey, @Relation), mint a Room. A kapcsolatok kézi SQL JOIN lekérdezésekkel valósíthatók meg a @Query-ben. Összetett relációs sémákhoz jobb megfontolni a Drift-et a beépített kapcsolattámogatásával.
Floor lehetővé teszi a callback visszahívás engedélyezését a DatabaseBuilder létrehozásakor — ebbe a sqflite.Database példánya kerül átadásra, amelyre naplózó akasztható. Alternatívaként használja a floor_doctor-t a séma és adatok megjelenítéséhez fejlesztői módban.
Floor a sqflite-ot használja, amely nem működik webes környezetben. A webhez külön build szükséges a sqlite3-mal WASM-on keresztül. A jelenlegi verzióban a Floor hivatalosan az Android, iOS és macOS rendszereket támogatja. Webhez használja a Drift-et a sqlite3 adapterrel.
Floor nem rendelkezik beépített gyorsítótárazással — minden lekérdezés az SQLite-hoz hajtódik végre. Az ismétlődő lekérdezések gyorsítótárazásához használjon Repository réteget memóriabeli gyorsítótárral (például dart_cache). A Floor csak kódot generál az SQLite-tal való munkához, anélkül, hogy rétegeket adna hozzá.
Összegzés
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is