Floor — Flutter के लिए ORM (Object-Relational Mapping) है, जो SQLite के ऊपर एक टाइप की गई परत प्रदान करता है। raw SQLite क्वेरीज़ के विपरीत, Floor एनोटेटेड Dart मॉडल से DAO क्लासेज़ जनरेट करता है। Pub.dev, 2024 के अनुसार, Floor का उपयोग 3500 से अधिक Flutter प्रोजेक्ट्स में होता है और यह drift और hive के साथ स्थानीय डेटा स्टोरेज के लिए तीन सबसे लोकप्रिय ORM समाधानों में से एक है।
मुख्य बिंदु
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 तीन परतों से बना है: Entity (तालिका मॉडल), DAO (क्वेरी इंटरफ़ेस) और Database (प्रवेश बिंदु)। जनरेटर फ़ील्ड मैपिंग के लिए _$_Entity इम्प्लीमेंटेशन और SQL निष्पादन के लिए _$_Dao बनाता है। जब Entity या DAO बदलता है, तो build_runner को पुनरारंभ करना पर्याप्त है — कोड स्वचालित रूप से अपडेट होता है। स्कीमा संस्करणों के बीच माइग्रेशन के लिए, Floor अनुक्रमिक संस्करण संख्याओं का उपयोग करता है, जो उपयोगकर्ता उपकरणों पर ऐप अपडेट करते समय डेटा अखंडता सुनिश्चित करता है।
Floor प्लेटफ़ॉर्म बिल्ड के लिए sqflite पैकेज और डेस्कटॉप और वेब के लिए sqlite3 के माध्यम से SQLite का उपयोग करता है। जब ऐप शुरू होता है, Floor SQLite फ़ाइल बनाता या खोलता है, माइग्रेशन लागू करता है और क्वेरी निष्पादित करने के लिए DAO विधियाँ तैयार करता है। सभी ऑपरेशन Future और Stream के माध्यम से एसिंक्रोनस रूप से निष्पादित होते हैं।
Floor में कोड जनरेशन इस प्रकार काम करता है: पार्सर स्रोत फ़ाइलों से एनोटेशन पढ़ता है, मॉडल और क्वेरीज़ का AST (Abstract Syntax Tree) बनाता है, फिर _$ उपसर्ग के साथ Dart फ़ाइलें जनरेट करता है। जनरेटेड कोड में ResultSet → Entity मैपर और इसके विपरीत शामिल हैं।
Floor एक एकल isolate में SQLite के साथ काम करता है। सभी क्वेरीज़ एसिंक्रोनस रूप से निष्पादित होती हैं, लेकिन समवर्ती लेखन SQLite स्तर पर लॉक होते हैं। ट्रांज़ैक्शन के लिए, @transaction एनोटेशन का उपयोग किया जाता है, जो क्वेरीज़ के समूह की परमाणुता और त्रुटि पर रोलबैक सुनिश्चित करता है।
Floor और Drift दोनों SQLite के ऊपर ORM हैं, लेकिन वे दर्शन में भिन्न हैं। Floor Android के Room के करीब है, Drift अंतर्निहित Stream API और SQL फ़ाइलों के माध्यम से क्वेरी संकलन के साथ अधिक रिएक्टिव है। उनके बीच चुनाव टीम के अनुभव और आवश्यक रिएक्टिविटी पर निर्भर करता है।
| विशेषता | Floor | Drift |
|---|---|---|
| क्वेरी प्रकार | @Query में SQL स्ट्रिंग्स | Dart विधियाँ + sql फ़ाइलें |
| कोड जनरेशन | floor_generator (build_runner) | drift_dev (build_runner) |
| रिएक्टिविटी | DAO से Stream | अंतर्निहित Stream API + ऑटो-अपडेटिंग |
| जटिलता | कम (परिचित SQL) | मध्यम (स्वयं का DSL) |
| माइग्रेशन | मैन्युअल SQL स्क्रिप्ट | स्वचालित + मैन्युअल |
| संगतता | Android, iOS, macOS | Android, iOS, Web, macOS, Linux |
Floor उन टीमों के लिए विकल्प है जो पहले से SQL और Android Room से परिचित हैं। यदि डेवलपर्स मैन्युअल रूप से SQL क्वेरी लिखने के आदी हैं और SQLite के ऊपर न्यूनतम आवरण चाहते हैं — तो Floor नया DSL सीखे बिना टाइपिंग प्रदान करता है। यह डीबग करना भी आसान है क्योंकि जनरेटेड कोड पढ़ने योग्य और पूर्वानुमेय है।
Drift अधिक शक्तिशाली रिएक्टिविटी प्रदान करता है और अधिक प्लेटफ़ॉर्म का समर्थन करता है। यदि ऐप UI अपडेट के लिए Stream का सक्रिय रूप से उपयोग करता है, JOIN और सबक्वेरीज़ के साथ जटिल क्वेरी की आवश्यकता है, या वेब को लक्षित करता है — Drift बेहतर है। हालांकि, इसके स्वयं के DSL को सीखने की आवश्यकता के कारण इसकी प्रवेश बाधा अधिक है।
Floor एनोटेशन के आसपास बनाया गया है। नीचे टास्क लिस्ट ऐप के लिए Entity, DAO और Database का पूरा उदाहरण दिया गया है। build_runner चलाने के बाद, जनरेटेड क्लासेज़ उपयोग के लिए तैयार हैं।
TaskEntity क्लास @Entity एनोटेशन के साथ task तालिका पर मैप होती है। @primaryKey वाला फ़ील्ड प्राथमिक कुंजी बन जाता है। TaskDao इंटरफ़ेस में तालिका संचालन के लिए विधियाँ हैं — प्रत्येक विधि @Query, @Insert, @Update या @Delete से एनोटेड है।
@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 लौटाता है।
@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();
Floor DAO विधियों से Stream लौटाने का समर्थन करता है। तालिका में किसी भी बदलाव पर, Stream एक नई सूची उत्सर्जित करता है। यह Flutter में StreamBuilder के साथ एकीकृत होता है — जब रिकॉर्ड जोड़े, संशोधित या हटाए जाते हैं तो UI स्वचालित रूप से अपडेट होता है।
@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 @Database एनोटेशन में version पैरामीटर के माध्यम से डेटाबेस वर्ज़निंग का समर्थन करता है। जब Entity बदलता है (फ़ील्ड जोड़ना या हटाना), तो आपको वर्ज़न बढ़ाने और माइग्रेशन जोड़ने की आवश्यकता है। माइग्रेशन एक Dart फ़ंक्शन है जो ट्रांज़ैक्शन प्राप्त करता है और ALTER TABLE SQL क्वेरी निष्पादित करता है।
मान लें कि वर्ज़न 2 में हमने TaskEntity में dueDate फ़ील्ड जोड़ा। माइग्रेशन ALTER TABLE SQL क्वेरी के माध्यम से किया जाता है। यदि माइग्रेशन निर्दिष्ट नहीं है, Floor MigrationStrategy को कॉल करता है जहाँ आप fallback सेट कर सकते हैं (उदाहरण के लिए, डेटा हानि के साथ तालिका को पुनः बनाना)।
Floor अंतर्निहित मॉक फ्रेमवर्क प्रदान नहीं करता, लेकिन डेटाबेस को परीक्षणों में आसानी से बदला जा सकता है। inMemoryDatabaseBuilder बनाएँ — यह स्कीमा में प्रोडक्शन के समान मेमोरी में SQLite डेटाबेस बनाता है। प्रत्येक परीक्षण के बाद, परीक्षण परिदृश्यों को अलग करने के लिए deleteDatabase के माध्यम से डेटा साफ़ करें।
Floor DAO विधियों पर @transaction एनोटेशन के माध्यम से ट्रांज़ैक्शन का समर्थन करता है। ट्रांज़ैक्शन के अंदर, कई क्वेरीज़ त्रुटि पर रोलबैक गारंटी के साथ क्रमिक रूप से निष्पादित होती हैं। List
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();
अक्सर पूछे जाने वाले प्रश्न
sqflite में मैन्युअल रूप से SQL क्वेरी लिखने और ResultSet को ऑब्जेक्ट में मैप करने की आवश्यकता होती है। Floor यह कोड स्वचालित रूप से जनरेट करता है: आप Entity और DAO का वर्णन करते हैं, और टाइप की गई विधियाँ उपयोग के लिए तैयार Dart ऑब्जेक्ट लौटाती हैं। Floor एनोटेशन के माध्यम से कंपाइल टाइम पर SQL क्वेरीज़ की भी जाँच करता है।
Floor में Room जैसे संबंधों के लिए अंतर्निहित एनोटेशन (ForeignKey, @Relation) नहीं हैं। संबंध @Query में मैन्युअल SQL JOIN क्वेरी के माध्यम से कार्यान्वित किए जाते हैं। जटिल रिलेशनल स्कीमा के लिए, अंतर्निहित संबंध समर्थन वाले Drift पर विचार करें।
Floor DatabaseBuilder बनाते समय callback सक्षम करने की अनुमति देता है — इसे sqflite.Database का एक इंस्टेंस प्राप्त होता है जिस पर आप लॉगर लगा सकते हैं। वैकल्पिक रूप से, डेव मोड में स्कीमा और डेटा देखने के लिए floor_doctor का उपयोग करें।
Floor sqflite का उपयोग करता है, जो वेब वातावरण में काम नहीं करता। वेब के लिए, WASM के माध्यम से sqlite3 के साथ एक अलग बिल्ड की आवश्यकता है। वर्तमान संस्करण में, Floor आधिकारिक रूप से Android, iOS और macOS का समर्थन करता है। वेब के लिए, sqlite3 एडाप्टर के साथ Drift का उपयोग करें।
Floor में अंतर्निहित कैशिंग नहीं है — प्रत्येक क्वेरी SQLite पर निष्पादित होती है। बार-बार की जाने वाली क्वेरी को कैश करने के लिए, इन-मेमोरी कैश (उदाहरण के लिए, dart_cache) के साथ Repository परत का उपयोग करें। Floor केवल SQLite के साथ काम करने के लिए कोड जनरेट करता है, उसके ऊपर कोई अतिरिक्त बोझ नहीं डालता।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें