Floor — यह क्या है, Flutter में SQLite के ऊपर ORM

लेखक: IT Sectr प्रकाशित: 2026-03-13 पढ़ने का समय: 9 मिनट

Floor — Flutter के लिए ORM (Object-Relational Mapping) है, जो SQLite के ऊपर एक टाइप की गई परत प्रदान करता है। raw SQLite क्वेरीज़ के विपरीत, Floor एनोटेटेड Dart मॉडल से DAO क्लासेज़ जनरेट करता है। Pub.dev, 2024 के अनुसार, Floor का उपयोग 3500 से अधिक Flutter प्रोजेक्ट्स में होता है और यह drift और hive के साथ स्थानीय डेटा स्टोरेज के लिए तीन सबसे लोकप्रिय ORM समाधानों में से एक है।

मुख्य बिंदु

  • Floor — एनोटेशन के माध्यम से DAO और Entity की कोड जनरेशन के साथ SQLite के ऊपर ORM
  • टाइप सुरक्षा — क्वेरीज़ कंपाइल टाइम पर जाँची जाती हैं, रनटाइम SQL त्रुटियों को समाप्त करती हैं
  • DAO पैटर्न — Data Access Object SQL क्वेरीज़ को Dart विधियों में समाहित करता है
  • माइग्रेशन — SQLite स्कीमा वर्ज़निंग के लिए अंतर्निहित समर्थन
  • रिएक्टिविटी — UI स्वचालित अपडेट के लिए Stream के माध्यम से Flow क्वेरीज़

Floor क्या है?

Floor SQLite के ऊपर बनी Flutter और Dart के लिए एक ORM लाइब्रेरी है। यह एंटिटी (Entity), Data Access Objects (DAO) और डेटाबेस (Database) का वर्णन करने के लिए एनोटेशन का उपयोग करती है। कोड जनरेशन build_runner और floor_generator के माध्यम से की जाती है — कंपाइलर DAO इम्प्लीमेंटेशन और एक प्रबंधक डेटाबेस क्लास बनाता है। raw sqflite के विपरीत, Floor टाइप रिफ्लेक्शन के माध्यम से कॉलम को Entity फ़ील्ड में स्वचालित रूप से मैप करके ResultSet से Dart ऑब्जेक्ट में मैन्युअल रूपांतरण की आवश्यकता को पूरी तरह समाप्त करता है।

Floor Android डेवलपर्स को Room से परिचित Repository + DAO पैटर्न का अनुसरण करता है। प्रत्येक तालिका को @Entity एनोटेशन वाली Dart क्लास द्वारा दर्शाया जाता है, SQL क्वेरीज़ को @dao एनोटेशन वाले इंटरफ़ेस में समूहित किया जाता है, और डेटाबेस को @Database वाली एब्सट्रैक्ट क्लास में इकट्ठा किया जाता है। यह दृष्टिकोण डेटा मॉडल को क्वेरी लॉजिक से सख्ती से अलग करता है।

Flutter Pulse (2023) के अनुसार, Floor को 28% Flutter प्रोजेक्ट्स में चुना जाता है जिन्हें स्थानीय डेटाबेस की आवश्यकता होती है। इसे चुनने के मुख्य कारण SQL से परिचितता (नई क्वेरी भाषा सीखने की आवश्यकता नहीं) और कंपाइल-टाइम क्वेरी जाँच हैं। इसके अलावा, Floor पढ़ने योग्य कोड जनरेट करता है जो कस्टम DSL वाले अधिक एब्सट्रैक्ट ORM की तुलना में डीबग करना आसान है, जो टीम में नए डेवलपर्स के लिए प्रवेश बाधा को कम करता है।

Floor आर्किटेक्चर

Floor तीन परतों से बना है: Entity (तालिका मॉडल), DAO (क्वेरी इंटरफ़ेस) और Database (प्रवेश बिंदु)। जनरेटर फ़ील्ड मैपिंग के लिए _$_Entity इम्प्लीमेंटेशन और SQL निष्पादन के लिए _$_Dao बनाता है। जब Entity या DAO बदलता है, तो build_runner को पुनरारंभ करना पर्याप्त है — कोड स्वचालित रूप से अपडेट होता है। स्कीमा संस्करणों के बीच माइग्रेशन के लिए, Floor अनुक्रमिक संस्करण संख्याओं का उपयोग करता है, जो उपयोगकर्ता उपकरणों पर ऐप अपडेट करते समय डेटा अखंडता सुनिश्चित करता है।

Flutter में Floor कैसे काम करता है?

Floor प्लेटफ़ॉर्म बिल्ड के लिए sqflite पैकेज और डेस्कटॉप और वेब के लिए sqlite3 के माध्यम से SQLite का उपयोग करता है। जब ऐप शुरू होता है, Floor SQLite फ़ाइल बनाता या खोलता है, माइग्रेशन लागू करता है और क्वेरी निष्पादित करने के लिए DAO विधियाँ तैयार करता है। सभी ऑपरेशन Future और Stream के माध्यम से एसिंक्रोनस रूप से निष्पादित होते हैं।

Floor में कोड जनरेशन इस प्रकार काम करता है: पार्सर स्रोत फ़ाइलों से एनोटेशन पढ़ता है, मॉडल और क्वेरीज़ का AST (Abstract Syntax Tree) बनाता है, फिर _$ उपसर्ग के साथ Dart फ़ाइलें जनरेट करता है। जनरेटेड कोड में ResultSet → Entity मैपर और इसके विपरीत शामिल हैं।

थ्रेड सुरक्षा

Floor एक एकल isolate में SQLite के साथ काम करता है। सभी क्वेरीज़ एसिंक्रोनस रूप से निष्पादित होती हैं, लेकिन समवर्ती लेखन SQLite स्तर पर लॉक होते हैं। ट्रांज़ैक्शन के लिए, @transaction एनोटेशन का उपयोग किया जाता है, जो क्वेरीज़ के समूह की परमाणुता और त्रुटि पर रोलबैक सुनिश्चित करता है।

Floor vs Drift: Flutter के लिए ORM तुलना

Floor और Drift दोनों SQLite के ऊपर ORM हैं, लेकिन वे दर्शन में भिन्न हैं। Floor Android के Room के करीब है, Drift अंतर्निहित Stream API और SQL फ़ाइलों के माध्यम से क्वेरी संकलन के साथ अधिक रिएक्टिव है। उनके बीच चुनाव टीम के अनुभव और आवश्यक रिएक्टिविटी पर निर्भर करता है।

विशेषताFloorDrift
क्वेरी प्रकार@Query में SQL स्ट्रिंग्सDart विधियाँ + sql फ़ाइलें
कोड जनरेशनfloor_generator (build_runner)drift_dev (build_runner)
रिएक्टिविटीDAO से Streamअंतर्निहित Stream API + ऑटो-अपडेटिंग
जटिलताकम (परिचित SQL)मध्यम (स्वयं का DSL)
माइग्रेशनमैन्युअल SQL स्क्रिप्टस्वचालित + मैन्युअल
संगतताAndroid, iOS, macOSAndroid, iOS, Web, macOS, Linux

Floor कब चुनें

Floor उन टीमों के लिए विकल्प है जो पहले से SQL और Android Room से परिचित हैं। यदि डेवलपर्स मैन्युअल रूप से SQL क्वेरी लिखने के आदी हैं और SQLite के ऊपर न्यूनतम आवरण चाहते हैं — तो Floor नया DSL सीखे बिना टाइपिंग प्रदान करता है। यह डीबग करना भी आसान है क्योंकि जनरेटेड कोड पढ़ने योग्य और पूर्वानुमेय है।

Drift कब बेहतर है

Drift अधिक शक्तिशाली रिएक्टिविटी प्रदान करता है और अधिक प्लेटफ़ॉर्म का समर्थन करता है। यदि ऐप UI अपडेट के लिए Stream का सक्रिय रूप से उपयोग करता है, JOIN और सबक्वेरीज़ के साथ जटिल क्वेरी की आवश्यकता है, या वेब को लक्षित करता है — Drift बेहतर है। हालांकि, इसके स्वयं के DSL को सीखने की आवश्यकता के कारण इसकी प्रवेश बाधा अधिक है।

Floor के साथ कोड उदाहरण

Floor एनोटेशन के आसपास बनाया गया है। नीचे टास्क लिस्ट ऐप के लिए Entity, DAO और Database का पूरा उदाहरण दिया गया है। build_runner चलाने के बाद, जनरेटेड क्लासेज़ उपयोग के लिए तैयार हैं।

Entity और DAO को परिभाषित करना

TaskEntity क्लास @Entity एनोटेशन के साथ task तालिका पर मैप होती है। @primaryKey वाला फ़ील्ड प्राथमिक कुंजी बन जाता है। TaskDao इंटरफ़ेस में तालिका संचालन के लिए विधियाँ हैं — प्रत्येक विधि @Query, @Insert, @Update या @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);
}

डेटाबेस आरंभीकरण

@Database एनोटेशन वाली एब्सट्रैक्ट क्लास Entity और DAO को जोड़ती है। databaseBuilder विधि डेटाबेस इंस्टेंस बनाती है। build कॉल करने के बाद, डेटाबेस तैयार है: Floor SQLite फ़ाइल खोलता है, माइग्रेशन लागू करता है और काम के लिए DAO लौटाता है।

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

// उपयोग
final database = await $FloorAppDatabase.databaseBuilder('app.db').build();
final taskDao = database.taskDao;
final tasks = await taskDao.getAllTasks();

Stream के माध्यम से रिएक्टिव क्वेरीज़

Floor DAO विधियों से Stream लौटाने का समर्थन करता है। तालिका में किसी भी बदलाव पर, Stream एक नई सूची उत्सर्जित करता है। यह Flutter में StreamBuilder के साथ एकीकृत होता है — जब रिकॉर्ड जोड़े, संशोधित या हटाए जाते हैं तो UI स्वचालित रूप से अपडेट होता है।

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

// Flutter विजेट में
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 में माइग्रेशन और वर्ज़निंग

Floor @Database एनोटेशन में version पैरामीटर के माध्यम से डेटाबेस वर्ज़निंग का समर्थन करता है। जब Entity बदलता है (फ़ील्ड जोड़ना या हटाना), तो आपको वर्ज़न बढ़ाने और माइग्रेशन जोड़ने की आवश्यकता है। माइग्रेशन एक Dart फ़ंक्शन है जो ट्रांज़ैक्शन प्राप्त करता है और ALTER TABLE SQL क्वेरी निष्पादित करता है।

माइग्रेशन उदाहरण

मान लें कि वर्ज़न 2 में हमने TaskEntity में dueDate फ़ील्ड जोड़ा। माइग्रेशन ALTER TABLE SQL क्वेरी के माध्यम से किया जाता है। यदि माइग्रेशन निर्दिष्ट नहीं है, Floor MigrationStrategy को कॉल करता है जहाँ आप fallback सेट कर सकते हैं (उदाहरण के लिए, डेटा हानि के साथ तालिका को पुनः बनाना)।

Floor क्वेरीज़ का परीक्षण

Floor अंतर्निहित मॉक फ्रेमवर्क प्रदान नहीं करता, लेकिन डेटाबेस को परीक्षणों में आसानी से बदला जा सकता है। inMemoryDatabaseBuilder बनाएँ — यह स्कीमा में प्रोडक्शन के समान मेमोरी में SQLite डेटाबेस बनाता है। प्रत्येक परीक्षण के बाद, परीक्षण परिदृश्यों को अलग करने के लिए deleteDatabase के माध्यम से डेटा साफ़ करें।

Floor में ट्रांज़ैक्शन और बैच ऑपरेशन

Floor DAO विधियों पर @transaction एनोटेशन के माध्यम से ट्रांज़ैक्शन का समर्थन करता है। ट्रांज़ैक्शन के अंदर, कई क्वेरीज़ त्रुटि पर रोलबैक गारंटी के साथ क्रमिक रूप से निष्पादित होती हैं। List पैरामीटर के साथ @Insert के माध्यम से बैच सम्मिलन एक कॉल में कई रिकॉर्ड सम्मिलित करने को अनुकूलित करता है — यह लूप में एक बार में एक रिकॉर्ड सम्मिलित करने से कई गुना तेज़ है। बल्क ऑपरेशन के लिए, 100–200 रिकॉर्ड के बैच सम्मिलन का उपयोग करें: यह सीमित संसाधनों वाले मोबाइल उपकरणों पर निष्पादन गति और RAM खपत के बीच इष्टतम संतुलन है।

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

अक्सर पूछे जाने वाले प्रश्न

Floor raw sqflite से कैसे अलग है?

sqflite में मैन्युअल रूप से SQL क्वेरी लिखने और ResultSet को ऑब्जेक्ट में मैप करने की आवश्यकता होती है। Floor यह कोड स्वचालित रूप से जनरेट करता है: आप Entity और DAO का वर्णन करते हैं, और टाइप की गई विधियाँ उपयोग के लिए तैयार Dart ऑब्जेक्ट लौटाती हैं। Floor एनोटेशन के माध्यम से कंपाइल टाइम पर SQL क्वेरीज़ की भी जाँच करता है।

क्या Floor तालिकाओं के बीच संबंधों का समर्थन करता है?

Floor में Room जैसे संबंधों के लिए अंतर्निहित एनोटेशन (ForeignKey, @Relation) नहीं हैं। संबंध @Query में मैन्युअल SQL JOIN क्वेरी के माध्यम से कार्यान्वित किए जाते हैं। जटिल रिलेशनल स्कीमा के लिए, अंतर्निहित संबंध समर्थन वाले Drift पर विचार करें।

Floor SQL क्वेरीज़ को कैसे डीबग करें?

Floor DatabaseBuilder बनाते समय callback सक्षम करने की अनुमति देता है — इसे sqflite.Database का एक इंस्टेंस प्राप्त होता है जिस पर आप लॉगर लगा सकते हैं। वैकल्पिक रूप से, डेव मोड में स्कीमा और डेटा देखने के लिए floor_doctor का उपयोग करें।

क्या Floor का उपयोग वेब बिल्ड के लिए किया जा सकता है?

Floor sqflite का उपयोग करता है, जो वेब वातावरण में काम नहीं करता। वेब के लिए, WASM के माध्यम से sqlite3 के साथ एक अलग बिल्ड की आवश्यकता है। वर्तमान संस्करण में, Floor आधिकारिक रूप से Android, iOS और macOS का समर्थन करता है। वेब के लिए, sqlite3 एडाप्टर के साथ Drift का उपयोग करें।

Floor में क्वेरी कैशिंग कैसे काम करती है?

Floor में अंतर्निहित कैशिंग नहीं है — प्रत्येक क्वेरी SQLite पर निष्पादित होती है। बार-बार की जाने वाली क्वेरी को कैश करने के लिए, इन-मेमोरी कैश (उदाहरण के लिए, dart_cache) के साथ Repository परत का उपयोग करें। Floor केवल SQLite के साथ काम करने के लिए कोड जनरेट करता है, उसके ऊपर कोई अतिरिक्त बोझ नहीं डालता।

सारांश

  • Floor — एनोटेशन के माध्यम से Entity, DAO और Database की कोड जनरेशन के साथ SQLite के ऊपर ORM
  • टाइप सुरक्षा — @Query एनोटेशन के माध्यम से SQL क्वेरीज़ कंपाइल टाइम पर जाँची जाती हैं
  • DAO पैटर्न — SQL क्वेरीज़ Dart विधियों में समाहित की जाती हैं, मॉडल को लॉजिक से अलग करती हैं
  • माइग्रेशन — मैन्युअल ALTER TABLE के साथ Migration के माध्यम से स्कीमा वर्ज़निंग
  • रिएक्टिविटी — बदलावों पर UI स्वचालित अपडेट के लिए DAO से Stream
  • सीमाएँ — कोई अंतर्निहित संबंध नहीं, वेब बिल्ड का समर्थन नहीं करता
  • अनुशंसा — Flutter प्रोजेक्ट्स के लिए Floor चुनें जहाँ टीम SQL और Room दृष्टिकोण से परिचित हो

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें