Floor — ano ito, ORM sa ibabaw ng SQLite sa Flutter

May-akda: IT Sectr Nai-publish: 2026-03-13 Oras ng pagbabasa: 9 min

Floor — ORM (Object-Relational Mapping) para sa Flutter na nagbibigay ng may-type na layer sa ibabaw ng SQLite. Hindi tulad ng raw SQLite query, ang Floor ay bumubuo ng DAO class mula sa mga anotadong Dart model. Ayon sa datos ng Pub.dev, 2024, ang Floor ay ginagamit sa mahigit 3500 Flutter project at kabilang sa tatlong pinakasikat na ORM solution para sa lokal na pag-imbak ng datos kasama ng drift at hive.

Mga Pangunahing Punto

  • Floor — ORM sa ibabaw ng SQLite na may code generation ng DAO at Entity sa pamamagitan ng mga anotasyon
  • Kaligtasan ng uri — ang mga query ay sinusuri sa compilation, inaalis ang runtime error ng SQL
  • Pattern ng DAO — Data Access Object nag-eencapsulate ng SQL query sa Dart method
  • Migrasyon — built-in na suporta para sa versioning ng SQLite schema
  • Reaktibidad — Flow query sa pamamagitan ng Stream para sa awtomatikong pag-update ng UI

Ano ang Floor?

Floor — ay isang ORM library para sa Flutter at Dart na binuo sa ibabaw ng SQLite. Gumagamit ito ng mga anotasyon para ilarawan ang mga entity (Entity), Data Access Object (DAO) at database (Database). Ang code generation ay ginagawa sa pamamagitan ng build_runner at floor_generator — lumilikha ang compiler ng mga DAO implementation at ang managing database class. Hindi tulad ng raw sqflite, ganap na inaalis ng Floor ang pangangailangan para sa manu-manong conversion ng ResultSet sa Dart object, awtomatikong nagma-map ng mga column sa Entity field sa pamamagitan ng type reflection.

Ang Floor ay sumusunod sa pattern ng Repository + DAO na pamilyar sa mga Android developer mula sa Room. Ang bawat table ay kinakatawan ng isang Dart class na may anotasyong @Entity, ang mga SQL query ay pinagsama-sama sa mga interface na may anotasyong @dao, at ang database ay binuo sa isang abstract class na may @Database. Ang pamamaraang ito ay mahigpit na naghihiwalay ng data model at query logic.

Ayon sa Flutter Pulse (2023), ang Floor ay pinipili sa 28% ng Flutter project na nangangailangan ng lokal na database. Ang mga pangunahing dahilan ng pagpili — kaalaman sa SQL (hindi na kailangan matuto ng bagong query language) at pagsusuri ng query sa compilation. Bukod pa rito, ang Floor ay bumubuo ng nababasang code na madaling i-debug hindi tulad ng mas abstract na ORM na may custom na DSL, na nagpapababa ng threshold para sa mga bagong developer sa team.

Arkitektura ng Floor

Floor ay binubuo ng tatlong layer: Entity (model ng table), DAO (interface ng query) at Database (entry point). Lumilikha ang generator ng mga implementation na _$_Entity para sa pagma-map ng field at _$_Dao para sa pag-execute ng SQL. Kapag binago ang Entity o DAO, sapat na ang i-restart ang build_runner — awtomatikong maa-update ang code. Para sa migrasyon sa pagitan ng mga bersyon ng schema, gumagamit ang Floor ng sequential version number na naggarantiya ng integridad ng datos sa pag-update ng app sa mga device ng user.

Paano gumagana ang Floor sa Flutter?

Floor ay gumagamit ng SQLite sa pamamagitan ng package na sqflite para sa platform build at sqlite3 para sa desktop at web. Sa pagsisimula ng app, ang Floor ay lumilikha o nagbubukas ng SQLite file, nag-a-apply ng migrasyon at naghahanda ng DAO method para sa pag-execute ng query. Lahat ng operasyon ay ginagawa sa asynchronous mode sa pamamagitan ng Future at Stream.

Ang code generation sa Floor ay gumagana ayon sa sumusunod na prinsipyo: binabasa ng parser ang mga anotasyon mula sa source code, lumilikha ng AST (Abstract Syntax Tree) ng mga modelo at query, pagkatapos ay bumubuo ng Dart file na may prefix na _$. Ang nabuong code ay may kasamang mapper para sa ResultSet → Entity at vice versa.

Kaligtasan ng thread

Floor ay gumagana sa SQLite sa isang isolate. Lahat ng query ay ginagawa nang asynchronous, ngunit ang concurrent na pagsulat ay na-block sa antas ng SQLite. Para sa transaksyon, ginagamit ang anotasyong @transaction na naggarantiya ng atomicity ng group ng query at rollback sa error.

Floor vs Drift: paghahambing ng ORM para sa Flutter

Parehong Floor at Drift — ay ORM sa ibabaw ng SQLite, ngunit nagkakaiba sila sa pilosopiya. Ang Floor ay mas malapit sa Room mula sa Android, ang Drift — ay mas reaktibo na may built-in na Stream API at compilation ng query sa pamamagitan ng SQL file. Ang pagpili sa pagitan nila ay depende sa karanasan ng team at kinakailangang reaktibidad.

KatangianFloorDrift
Uri ng querySQL string sa @QueryDart method + sql file
Code generationfloor_generator (build_runner)drift_dev (build_runner)
ReaktibidadStream mula sa DAOBuilt-in Stream API + auto-updating
KompleksidadMababa (pamilyar na SQL)Katamtaman (sariling DSL)
MigrasyonManu-manong SQL scriptAwtomatiko + manu-mano
KompatibilidadAndroid, iOS, macOSAndroid, iOS, Web, macOS, Linux

Kailan pumili ng Floor

Floor — pagpili ng mga team na pamilyar na sa SQL at Android Room. Kung ang mga developer ay sanay na magsulat ng SQL query nang manu-mano at gusto ng minimal na wrapper sa ibabaw ng SQLite — nagbibigay ang Floor ng typing nang hindi natututo ng bagong DSL. Ito rin ay mas madaling i-debug dahil ang nabuong code ay nababasa at predictable.

Kailan mas maganda ang Drift

Drift ay nagbibigay ng mas malakas na reaktibidad at sumusuporta sa mas maraming platform. Kung ang app ay aktibong gumagamit ng Stream para sa pag-update ng UI, nangangailangan ng kumplikadong query na may JOIN at subquery, o binuo para sa web — mas preferred ang Drift. Gayunpaman, mas mataas ang threshold nito dahil sa pangangailangang matutunan ang sarili nitong DSL.

Mga halimbawa ng code gamit ang Floor

Floor ay binuo sa paligid ng mga anotasyon. Sa ibaba ay isang kumpletong halimbawa ng Entity, DAO at Database para sa isang task list app. Pagkatapos patakbuhin ang build_runner, ang mga nabuong class ay handa nang gamitin.

Depinisyon ng Entity at DAO

Ang class na TaskEntity na may anotasyong @Entity ay nagma-map sa table na task. Ang field na may @primaryKey ay nagiging primary key. Ang interface na TaskDao ay naglalaman ng method para sa operasyon sa table — bawat method ay anotado ng @Query, @Insert, @Update o @Delete.

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

Inisyalisasyon ng database

Ang abstract class na may anotasyong @Database ay nag-uugnay ng Entity at DAO. Ang method na databaseBuilder ay lumilikha ng instance ng database. Pagkatapos tawagin ang build, handa na ang database: binubuksan ng Floor ang SQLite file, nag-a-apply ng migrasyon at nagbabalik ng DAO para sa paggamit.

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

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

Reaktibong query sa pamamagitan ng Stream

Floor ay sumusuporta sa pagbabalik ng Stream mula sa DAO method. Sa anumang pagbabago sa table, ang Stream ay naglalabas ng bagong listahan. Ito ay nag-i-integrate sa StreamBuilder sa Flutter — awtomatikong nag-a-update ang UI sa pagdagdag, pagbabago o pagtanggal ng record.

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

// Sa Flutter widget
StreamBuilder<List<TaskEntity>>(
    stream: taskDao.watchAllTasks(),
    builder: (context, snapshot) {
        final tasks = snapshot.data ?? [];
        return ListView.builder(
            itemCount: tasks.length,
            itemBuilder: (_, i) => TaskTile(tasks[i]),
        );
    },
)

Migrasyon at versioning sa Floor

Floor ay sumusuporta sa versioning ng database sa pamamagitan ng parameter na version sa anotasyong @Database. Kapag binago ang Entity (pagdagdag o pagtanggal ng field), kailangan dagdagan ang version at magdagdag ng migrasyon. Ang migrasyon ay isang Dart function na tumatanggap ng transaksyon at nag-execute ng SQL query na ALTER TABLE.

Halimbawa ng migrasyon

Kunwari, sa version 2 ay nagdagdag kami ng field na dueDate sa TaskEntity. Ang migrasyon ay ginagawa sa pamamagitan ng SQL query na ALTER TABLE. Kung hindi tinukoy ang migrasyon, tinatawag ng Floor ang MigrationStrategy kung saan maaaring itakda ang fallback (halimbawa, muling paggawa ng table na may pagkawala ng datos).

Pag-test ng Floor query

Floor ay hindi nagbibigay ng built-in na mock framework, ngunit ang database ay madaling mapalitan sa mga test. Gumawa ng inMemoryDatabaseBuilder — lumilikha ito ng SQLite database sa memory, magkapareho ng schema sa production. Pagkatapos ng bawat test, linisin ang datos sa pamamagitan ng deleteDatabase para sa isolation ng test scenario.

Transaksyon at batch operation sa Floor

Floor ay sumusuporta sa transaksyon sa pamamagitan ng anotasyong @transaction sa DAO method. Sa loob ng transaksyon, maraming query ang ginagawa nang sunud-sunod na may garantiya ng rollback sa error. Ang batch insertion sa pamamagitan ng @Insert na may parameter na List<T> ay nag-o-optimize ng pagpasok ng maraming record sa isang tawag — ito ay ilang beses na mas mabilis kaysa sa paisa-isang pagpasok sa loop. Para sa malawakang operasyon, gumamit ng batch insertion na 100–200 record: ito ang optimal na balanse sa pagitan ng bilis ng execution at konsumo ng RAM sa mga mobile device na may limitadong resources.

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

Mga Madalas Itanong

Ano ang pagkakaiba ng Floor sa raw sqflite?

sqflite ay nangangailangan ng manu-manong pagsulat ng SQL query at pagma-map ng ResultSet sa mga object. Awtomatikong binuo ng Floor ang code na ito: inilalarawan mo ang Entity at DAO, at ang mga naka-type na method ay nagbabalik ng handa nang Dart object. Sinusuri rin ng Floor ang SQL query sa compilation sa pamamagitan ng mga anotasyon.

Sinusuportahan ba ng Floor ang relasyon sa pagitan ng table?

Floor ay walang built-in na anotasyon para sa relasyon (ForeignKey, @Relation) tulad ng Room. Ang relasyon ay na-implement sa pamamagitan ng manu-manong SQL JOIN query sa @Query. Para sa kumplikadong relational schema, mas mainam na isaalang-alang ang Drift na may built-in na suporta para sa relasyon.

Paano i-debug ang Floor SQL query?

Floor ay nagbibigay-daan sa pag-activate ng callback na callback sa paggawa ng DatabaseBuilder — ang instance ng sqflite.Database ay ipinapasa dito kung saan maaaring ikabit ang logger. Bilang alternatibo, gamitin ang floor_doctor para sa visualization ng schema at datos sa dev mode.

Maaari bang gamitin ang Floor para sa web build?

Floor ay gumagamit ng sqflite na hindi gumagana sa web environment. Para sa web, kailangan ng hiwalay na build na may sqlite3 sa pamamagitan ng WASM. Sa kasalukuyang bersyon, opisyal na sinusuportahan ng Floor ang Android, iOS at macOS. Para sa web, gamitin ang Drift na may sqlite3 adapter.

Paano gumagana ang caching ng query sa Floor?

Floor ay walang built-in na caching — bawat query ay ginagawa sa SQLite. Para sa caching ng paulit-ulit na query, gamitin ang Repository layer na may in-memory cache (halimbawa, dart_cache). Ang Floor ay bumubuo lamang ng code para sa paggawa gamit ang SQLite, nang hindi nagdadagdag ng mga layer sa ibabaw nito.

Buod

  • Floor — ORM sa ibabaw ng SQLite na may code generation ng Entity, DAO at Database sa pamamagitan ng mga anotasyon
  • Kaligtasan ng uri — SQL query ay sinusuri sa compilation sa pamamagitan ng anotasyong @Query
  • Pattern ng DAO — SQL query ay naka-encapsulate sa Dart method, pinaghihiwalay ang modelo at lohika
  • Migrasyon — versioning ng schema sa pamamagitan ng Migration na may manu-manong ALTER TABLE
  • Reaktibidad — Stream mula sa DAO para sa awtomatikong pag-update ng UI sa mga pagbabago
  • Limitasyon — walang built-in na relasyon, hindi sumusuporta sa web build
  • Rekomendasyon — piliin ang Floor para sa Flutter project kung saan pamilyar ang team sa SQL at Room approach

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din