Room Android میں SQLite کے ساتھ کام کرنے کے لیے ایک لائبریری ہے، جو Jetpack کا حصہ ہے۔ یہ خام SQLite پر تجرید کی ایک تہہ فراہم کرتی ہے، ٹیبل بنانے، سوالات پر عمل درآمد اور Kotlin اور Java اشیاء میں ڈیٹا کی تبدیلی کو خودکار کرتی ہے۔ Android Developers کے مطابق، Room بلڈ ٹائم پر SQL سوالات کو مرتب کرتا ہے، نحو کی درستگی اور Entity اور ٹیبل کے درمیان تعلقات کی جانچ کرتا ہے۔
اہم نکات
Room Android Jetpack کی ایک مستقل لائبریری ہے جو SQLite کے لیے آبجیکٹ-ریلیشنل میپنگ فراہم کرتی ہے۔ Room خام SQLite کے تین اہم مسائل حل کرتا ہے: ٹیبل بنانے کے لیے بڑی مقدار میں بویلرپلیٹ کوڈ لکھنا، مرتب وقت پر SQL سوالات کی توثیق کا فقدان، اور Cursor کو دستی طور پر اشیاء میں تبدیل کرنا۔
لائبریری ایک تشریح پروسیسر (kapt یا KSP) استعمال کرتی ہے جو بلڈ ٹائم پر تجریدی RoomDatabase اور DAO کلاسز کا نفاذ تیار کرتا ہے۔ یہ اس بات کو یقینی بناتا ہے کہ SQL میں نحو کی غلطیاں اور قسم کی مماثلت ایپلیکیشن چلانے سے پہلے دریافت ہو جائیں، نہ کہ Google Play پر شائع کرنے کے بعد رن ٹائم پر۔
Google I/O 2023 کے مطابق، Room 68% Android ایپلیکیشنز میں استعمال ہوتا ہے جو مقامی ڈیٹا کے ساتھ کام کرتی ہیں۔ یہ ڈیوائس پر ڈیٹا اسٹوریج کا معیار ہے، جسے Google تمام نئے پروجیکٹس کے لیے تجویز کرتا ہے — فرسودہ SQLiteOpenHelper اور ContentProvider کے بجائے۔
Room کو ان پروجیکٹس میں شامل کریں جن میں سرور سے مقامی ڈیٹا کیشنگ، آف لائن موڈ، یا پیچیدہ SQL سوالات چلانے کی صلاحیت کے ساتھ ساختہ صارف ڈیٹا اسٹور کرنے کی ضرورت ہے۔
Room Android Jetpack کا حصہ ہے اور Google کی طرف سے مقامی ڈیٹا کے ساتھ کام کرنے والے تمام نئے پروجیکٹس کے لیے سرکاری طور پر تجویز کردہ ہے۔ Realm یا ObjectBox کے برعکس، Room مقامی SQLite استعمال کرتا ہے، جو DB Browser سے DataGrip تک کسی بھی تیسرے فریق کے ڈیٹا بیس ٹول کے ساتھ مطابقت کو یقینی بناتا ہے۔ ڈویلپر ایپلیکیشن کی .db فائل کھول سکتے ہیں اور براہ راست SQL سوالات چلا سکتے ہیں، جو ڈویلپمنٹ کے دوران ڈیبگنگ اور ڈیٹا تجزیہ کو آسان بناتا ہے۔
Entity ایک ڈیٹا کلاس ہے جس پر @Entity کا نشان لگا ہوتا ہے، جسے Room ڈیٹا بیس ٹیبل میں تبدیل کرتا ہے۔ کلاس کا ہر فیلڈ ٹیبل کا ایک کالم بن جاتا ہے، اور ہر مثال ایک قطار بن جاتی ہے۔ Room فیلڈز تک رسائی کے لیے ریفلیکشن استعمال کرتا ہے، لہذا لازمی شناخت کنندہ کے لیے @PrimaryKey تشریح ضروری ہے۔
@Entity تشریح Room کو بتاتی ہے کہ کلاس ایک ٹیبل ہے۔ tableName پیرامیٹر ٹیبل کا نام متعین کرتا ہے اگر وہ کلاس کے نام سے مختلف ہو۔ @PrimaryKey autoGenerate = true کے ذریعے خودکار تخلیق کی حمایت کے ساتھ بنیادی کلید کی وضاحت کرتا ہے۔
@Entity(tableName = "users")
data class User(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
@ColumnInfo(name = "full_name")
val name: String,
@Ignore
val tempData: String?
)
@ColumnInfo ٹیبل میں کالم کا نام متعین کرتا ہے اگر وہ Kotlin فیلڈ کے نام سے مختلف ہو۔ @Ignore ایک فیلڈ کو ٹیبل سے خارج کرتا ہے — یہ ڈیٹا بیس میں محفوظ نہیں ہوگا۔ @ForeignKey حذف یا اپ ڈیٹ پر جھڑپ کے عمل کے ساتھ ٹیبلوں کے درمیان تعلقات کے لیے غیر ملکی کنجیوں کی وضاحت کرتا ہے۔
Room @Embedded تشریح کے ذریعے اندرونی اشیاء کو سپورٹ کرتا ہے۔ اندرونی کلاس کے فیلڈز نام کے تصادم سے بچنے کے لیے سابقے کے ساتھ والدین کے ٹیبل کے کالموں میں پھیل جاتے ہیں۔ مثال کے طور پر، User میں شامل city اور street فیلڈز والی Address کلاس users ٹیبل میں address_city اور address_street کالم بنائے گی، سادہ ویلیو آبجیکٹ کے لیے علیحدہ ٹیبل کی ضرورت کو ختم کرتے ہوئے۔
Room صرف قدیمی اقسام اور ان کے ریپر کو سپورٹ کرتا ہے۔ فہرستیں، Date یا حسب ضرورت اقسام کو ذخیرہ کرنے کے لیے، @TypeConverter استعمال کریں — حسب ضرورت قسم اور SQLite قدیمی قسم کے درمیان تبدیلی کے لیے جامد طریقے، مثال کے طور پر، List اور JSON سٹرنگ کے درمیان۔
DAO (ڈیٹا تک رسائی کا آبجیکٹ) ایک انٹرفیس یا تجریدی کلاس ہے جس پر @Dao کا نشان لگا ہوتا ہے، جس میں ڈیٹا تک رسائی کے طریقے ہوتے ہیں۔ ہر طریقہ ایک SQL آپریشن سے نشان زد ہوتا ہے: @Insert، @Update، @Delete یا واضح SQL سوال کے ساتھ @Query۔
@Query تشریح ایک SQL سٹرنگ لیتی ہے جسے Room مرتب وقت پر نحو کی درستگی اور Entity فیلڈز کے ساتھ کالم کے ناموں کی مماثلت کے لیے تصدیق کرتا ہے۔ Room :paramName نحو کے ذریعے پیرامیٹرائزڈ سوالات کو سپورٹ کرتا ہے۔
@Dao
interface UserDao {
@Query("SELECT * FROM users WHERE id = :userId")
suspend fun getUserById(userId: Int): User?
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertUser(user: User)
@Query("SELECT * FROM users ORDER BY name ASC")
fun getAllUsers(): Flow<List<User>>
}
@Insert ڈپلیکیٹ ریکارڈ داخل کرتے وقت تنازعات کو سنبھالنے کے لیے OnConflictStrategy کے اختیارات کو سپورٹ کرتا ہے۔ واپسی کی قسم کے طور پر Flow ٹیبل میں ڈیٹا کی ہر تبدیلی پر رد عمل والی UI اپ ڈیٹس فراہم کرتا ہے — سبسکرپشن کسی بھی INSERT، UPDATE یا DELETE پر خود بخود دوبارہ شروع ہو جاتی ہے۔
@Transaction تشریح ایک ٹرانزیکشن بلاک میں متعدد کارروائیوں کے جوہری عمل درآمد کی ضمانت دیتی ہے۔ Room عمل درآمد کے دوران ڈیٹا بیس کو مقفل کرتا ہے، متعدد تھریڈز سے بیک وقت رسائی کے دوران ریس کنڈیشن کو روکتا ہے۔
RoomDatabase ایک تجریدی کلاس ہے جو Entity اور DAO کو ڈیٹا بیس تک رسائی کے ایک نقطہ میں یکجا کرتی ہے۔ یہ اسکیما ورژن اور Entity کلاسز کی فہرست کے ساتھ Room.databaseBuilder کے ذریعے بنائی جاتی ہے۔ ڈیٹا بیس کی مثال کو متعدد کنیکشنز سے بچنے کے لیے lazy delegation کے ذریعے سنگلٹن کے طور پر بنایا جانا چاہیے۔
Room میں منتقلی ایک Migration کلاس ہے جو پرانے اسکیما ورژن سے نئے میں منتقلی کے لیے SQL اسکرپٹ بیان کرتی ہے۔ اگر اسکیما تبدیل ہونے پر منتقلی فراہم نہیں کی جاتی ہے، Room IllegalStateException پھینکتا ہے۔ یہ ایپلیکیشن اپ ڈیٹ کرتے وقت حادثاتی صارف ڈیٹا کے نقصان سے بچاتا ہے۔
val migration_1_2 = object : Migration(1, 2) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE users ADD COLUMN age INTEGER NOT NULL DEFAULT 0")
}
}
val db = Room.databaseBuilder(
getApplication(),
AppDatabase::class.java,
"app_database"
).addMigrations(migration_1_2)
.build()
ڈویلپمنٹ کے لیے آپ fallbackToDestructiveMigration استعمال کر سکتے ہیں، جو ورژن کی عدم مطابقت پر پرانے ڈیٹا بیس کو حذف کرکے نیا بناتا ہے۔ یہ موڈ صرف ڈیبگنگ کے لیے ہے — پروڈکشن ریلیز میں مناسب منتقلی اسکرپٹ شامل ہونی چاہیے۔
ڈیٹا بیس کی جانچ کے لیے، Room ایک خاص کلاس Room.inMemoryTestBuilder فراہم کرتا ہے جو ڈسک پر محفوظ کیے بغیر میموری میں ڈیٹا بیس بناتا ہے۔ ہر ٹیسٹ مکمل ہونے کے بعد، ڈیٹا بیس خود بخود تباہ ہو جاتا ہے، ٹیسٹ کے منظرناموں کی مکمل تنہائی کو یقینی بناتا ہے۔ android-arch-core-testing لائبریری کے ساتھ مل کر، ڈویلپر دستی طور پر حالت صاف کیے بغیر ڈیٹا بیس کی زندگی کے چکر کا انتظام کر سکتے ہیں اور منتقلی کی درستگی کی تصدیق کر سکتے ہیں۔
Room کی کارکردگی براہ راست سوال کی ساخت اور اشاریوں پر منحصر ہے۔ سست سوالات کے تجزیہ کے لیے، Room enableQueryCallback پرچم فراہم کرتا ہے، جو عمل درآمد کے وقت کے ساتھ تمام SQL سوالات کو لاگ کرتا ہے۔ ڈویلپر اس لاگ کا استعمال 100 ملی سیکنڈ سے زیادہ وقت لینے والے سوالات کو تلاش کرنے اور @Entity میں @Index تشریح کے ذریعے مرکب اشاریے شامل کرکے یا @Relation استعمال کرتے ہوئے ذیلی سوالات کو براہ راست JOIN کارروائیوں میں دوبارہ لکھ کر بہتر بنانے کے لیے کر سکتے ہیں۔
Room SQLCipher کے ذریعے ڈیٹا بیس کی خفیہ کاری کو بھی سپورٹ کرتا ہے۔ net.zetetic:android-database-sqlcipher لائبریری شامل کرنا اور معیاری کے بجائے SupportFactory استعمال کرنا DAO سوالات یا Entity ساخت کو تبدیل کیے بغیر ڈسک پر موجود تمام ڈیٹا کی شفاف خفیہ کاری فراہم کرتا ہے۔ یہ صارفین کے ذاتی ڈیٹا کو سنبھالنے والی ایپلیکیشنز کے لیے ضروری ہے اور GDPR اور ذاتی ڈیٹا کے تحفظ سے متعلق روسی وفاقی قانون 152-FZ کی تعمیل کرتا ہے۔ خفیہ کاری کا پاس ورڈ روٹ کیے گئے آلات پر ٹولنگ کے ذریعے نکالنے سے بچانے کے لیے Android Keystore میں محفوظ کیا جا سکتا ہے۔
Room ورژن 2.1 سے Kotlin Coroutines کو مقامی طور پر سپورٹ کرتا ہے۔ DAO کے طریقے suspend فنکشن ہو سکتے ہیں جو مرکزی تھریڈ کو روکے بغیر بیک گراؤنڈ تھریڈ میں سوالات انجام دیتے ہیں۔ Room ڈسپیچرز کو خود بخود منظم کرتا ہے، پڑھنے اور لکھنے کے سوالات کے لیے Dispatchers.IO استعمال کرتا ہے۔
رد عمل والے سوالات کے لیے، Room ایک Flow لوٹاتا ہے — ایک سرد ڈیٹا سٹریم جو متاثرہ ٹیبل میں ہر تبدیلی پر ایک نئی قدر جاری کرتا ہے۔ ViewModel stateIn یا collect کے ذریعے Flow کو سبسکرائب کرتا ہے، اڈاپٹر کو دستی طور پر مطلع کیے بغیر خودکار UI اپ ڈیٹس فراہم کرتا ہے۔
Room SQLite سے صفحہ بہ صفحہ ڈیٹا لوڈ کرنے والے ایک خاص PagingSource نفاذ کے ذریعے Paging 3 کو بھی سپورٹ کرتا ہے۔ یہ ہزاروں ریکارڈ والی بڑی فہرستوں کے لیے موثر ہے: Paging 3 صرف اسکرین پر نظر آنے والی قطاریں لوڈ کرتا ہے اور ڈیٹا بیس میں تبدیلیوں پر انہیں خود بخود اپ ڈیٹ کرتا ہے۔
آف لائن رسائی اور لامحدود اسکرولنگ کے ساتھ نیوز فیڈز، آپریشن لاگز یا پروڈکٹ کی فہرستیں دکھانے کے لیے Room کے ساتھ Paging 3 استعمال کریں۔
اکثر پوچھے گئے سوالات
Room ٹیبل بنانے، Cursor کو آبجیکٹ میں تبدیل کرنے اور مرتب وقت پر SQL توثیق کو خودکار کرتا ہے۔ SQLiteOpenHelper کو دستی طور پر اسکیما لکھنے، Cursor کو سنبھالنے کی ضرورت ہوتی ہے اور ایپلیکیشن چلانے سے پہلے سوال کی توثیق نہیں ہوتی، جو غلطیوں کے خطرے کو بڑھاتا ہے۔
ہاں، Entity کو تبدیل کرتے وقت (فیلڈ شامل/ہٹانا، قسم تبدیل کرنا)، منتقلی ضروری ہے۔ اس کے بغیر، Room اسٹارٹ اپ پر IllegalStateException پھینکتا ہے۔ ڈویلپمنٹ کے لیے، آپ fallbackToDestructiveMigration کو فعال کر سکتے ہیں، لیکن پروڈکشن ریلیز میں درست منتقلی اسکرپٹ ضروری ہیں۔
Room جھڑپ کے عمل کے لیے @ForeignKey اور اندرونی اشیاء کے لیے @Relation کو سپورٹ کرتا ہے۔ پیچیدہ JOIN سوالات کے لیے، @Embedded اور @Relation کے ذریعے اندرونی ہستیوں کے ساتھ POJO واپس کرنے والے @Query کے ساتھ @Transaction تشریح استعمال کریں۔
ہاں، Room Java کے ساتھ مکمل طور پر مطابقت رکھتا ہے۔ suspend فنکشنز کے بجائے LiveData یا RxJava Observable استعمال کریں؛ Flow کے بجائے LiveData استعمال کریں۔ Java کے ساتھ Room وہی تمام تشریحات سپورٹ کرتا ہے، لیکن غیر متزامن کارروائیوں کے لیے زیادہ بویلرپلیٹ کوڈ کی ضرورت ہوتی ہے۔
Room Zetetic کے SQLCipher کے ذریعے خفیہ کاری کو سپورٹ کرتا ہے۔ Room.databaseBuilder کے بجائے، net.zetetic:android-database-sqlcipher لائبریری سے SupportFactory استعمال کریں، خفیہ کاری کا پاس ورڈ پاس کریں۔ ڈسک پر موجود تمام ڈیٹا DAO سوالات کے لیے شفاف طریقے سے خفیہ ہو جائے گا۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں