Room, Android Jetpack का एक ORM लाइब्रेरी है जो Android पर स्थानीय डेटाबेस के साथ काम करने के लिए SQLite के ऊपर एक एब्स्ट्रक्शन लेयर प्रदान करता है। Android Developers, 2025 की आधिकारिक दस्तावेज़ीकरण के अनुसार, Room संकलन समय पर एनोटेशन के आधार पर स्वचालित रूप से DAO इम्प्लीमेंटेशन जनरेट करता है, जो सीधे SQLiteOpenHelper के उपयोग की तुलना में लगभग 70% बॉयलरप्लेट कोड को समाप्त करता है। लाइब्रेरी संकलन चरण में SQL क्वेरी की वैलिडेशन करती है, जिससे डिवाइस पर एप्लिकेशन चलाने से पहले सिंटैक्स त्रुटियों का पता लगाया जा सकता है।
मुख्य बातें
Room, Android Jetpack का एक ORM लाइब्रेरी है जिसे Google ने Android प्लेटफ़ॉर्म पर स्थानीय SQLite डेटाबेस के साथ काम को सरल बनाने के लिए बनाया है। यह डेटा स्कीमा का वर्णन करने के लिए एनोटेशन प्रदान करता है और संकलन समय पर स्वचालित रूप से DAO इंटरफ़ेस इम्प्लीमेंटेशन जनरेट करता है। सीधे SQLiteOpenHelper के उपयोग के विपरीत, Room डेवलपर को डेटाबेस कनेक्शन बनाने, खोलने और प्रबंधित करने के लिए महत्वपूर्ण मात्रा में बॉयलरप्लेट कोड लिखने से मुक्त करता है।
इस लाइब्रेरी को Google I/O 2017 में Android आर्किटेक्चर घटकों के भाग के रूप में प्रस्तुत किया गया था। तब से, Room स्थानीय डेटा स्टोरेज के लिए डी-फैक्टो मानक बन गया है, जिसने Android के लिए GreenDAO और Realm जैसे समाधानों को लोकप्रियता में पीछे छोड़ दिया है। Google के अनुसार, यह लाइब्रेरी Google Play पर प्रकाशित 60% से अधिक एप्लिकेशन में उपयोग की जाती है जो डिवाइस पर स्थानीय डेटा के साथ काम करते हैं।
प्रमुख विशेषता — एनोटेशन प्रोसेसर की मदद से संकलन समय पर SQL क्वेरी की वैलिडेशन। यदि डेवलपर SQL कमांड में कोई गलती करता है, उदाहरण के लिए, एक गैर-मौजूद कॉलम नाम निर्दिष्ट करता है, तो एप्लिकेशन इंस्टॉल होने से पहले बिल्ड त्रुटि के साथ विफल हो जाएगा। यह SQLiteOpenHelper दृष्टिकोण से मौलिक रूप से अलग है, जहाँ ऐसी त्रुटियाँ केवल रनटाइम पर ही पता चलती हैं, अक्सर प्रोडक्शन में।
SQLite केवल पाँच डेटा प्रकारों का समर्थन करता है: TEXT, INTEGER, REAL, BLOB और NULL। हालाँकि, Java और Kotlin में जटिल प्रकारों का उपयोग किया जाता है: Date, List, Enum और कस्टम ऑब्जेक्ट। उन्हें सहेजने के लिए, Room TypeConverters तंत्र प्रदान करता है — स्थैतिक विधियाँ जो जटिल प्रकार को SQLite के लिए समझने योग्य आदिम प्रकार में परिवर्तित करती हैं। उदाहरण के लिए, Date ऑब्जेक्ट को Long (टाइमस्टैम्प) में, और List<String> को Gson या Moshi के माध्यम से JSON स्ट्रिंग में परिवर्तित किया जाता है।
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
val db = Room
.databaseBuilder(context, AppDatabase::class.java, "app-db")
.build()
कन्वर्टर घोषित करने के लिए, एक स्थैतिक विधि में @TypeConverter एनोटेशन जोड़ना और डेटाबेस स्तर पर @TypeConverters एनोटेशन में कन्वर्टर क्लास निर्दिष्ट करना पर्याप्त है। Room प्रत्येक SQL क्वेरी में संबंधित प्रकार को पढ़ने और लिखने पर स्वचालित रूप से कन्वर्टर लागू करता है, बिना मैन्युअल रूप से रूपांतरण विधियों को कॉल किए।
Room तीन मुख्य घटकों से बना है: Entity, DAO और Database। प्रत्येक एक सख्ती से परिभाषित भूमिका निभाता है और संबंधित एनोटेशन से एनोटेट किया जाता है। साथ मिलकर, वे एक पूर्ण डेटा एक्सेस लेयर बनाते हैं जो एप्लिकेशन के बिज़नेस लॉजिक को SQLite कार्यान्वयन विवरणों से अलग करता है।
Entity एक डेटा क्लास है जो डेटाबेस में एक तालिका की संरचना का वर्णन करता है। क्लास का प्रत्येक फ़ील्ड तालिका के एक कॉलम से मेल खाता है, और डेटाबेस में प्रत्येक पंक्ति क्लास के एक उदाहरण से मेल खाती है। @Entity एनोटेशन Room को बताता है कि क्लास एक तालिका है। @PrimaryKey एनोटेशन वाला फ़ील्ड प्राथमिक कुंजी निर्धारित करता है, जो ऑटो-इन्क्रीमेंट या समग्र हो सकती है। @ForeignKey का उपयोग तालिकाओं के बीच संबंधों के लिए किया जाता है, जो डेटाबेस स्तर पर डेटा अखंडता सुनिश्चित करता है।
@Entity(tableName = "users")
data class User(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
@ColumnInfo(name = "full_name")
val name: String,
val age: Int,
val email: String
)
DAO (Data Access Object) एक इंटरफ़ेस या एब्स्ट्रैक्ट क्लास है जो डेटा के साथ काम करने के लिए संचालन घोषित करता है: इन्सर्ट, रीड, अपडेट और डिलीट। प्रत्येक संचालन @Insert, @Query, @Update या @Delete से एनोटेट किया जाता है। Room संकलन समय पर इस इंटरफ़ेस का इम्प्लीमेंटेशन स्वचालित रूप से जनरेट करता है। @Query एनोटेशन विशेष रूप से मूल्यवान है — यह SQL क्वेरी को स्ट्रिंग के रूप में स्वीकार करता है और बिल्ड समय पर इसकी शुद्धता को मान्य करता है।
@Dao
interface UserDao {
@Insert
suspend fun insert(user: User): Long
@Query("SELECT * FROM users WHERE id = :userId")
suspend fun getUserById(userId: Int): User?
@Query("SELECT * FROM users")
fun getAllUsers(): Flow<List<User>>
@Delete
suspend fun delete(user: User)
}
Database एक एब्स्ट्रैक्ट क्लास है जो RoomDatabase का विस्तार करता है और डेटाबेस के प्रवेश बिंदु के रूप में कार्य करता है। इसमें सभी Entities की सूची होती है और DAO प्राप्त करने के लिए एब्स्ट्रैक्ट विधियाँ प्रदान करता है। क्लास @Database से एनोटेट किया जाता है, जो स्कीमा संस्करण और Entities की सूची निर्दिष्ट करता है। डेटाबेस इंस्टेंस ऐप कॉन्टेक्स्ट, फ़ाइल नाम और Database क्लास के साथ Room.databaseBuilder के माध्यम से बनाया जाता है।
Room SQLite को प्रतिस्थापित नहीं करता, बल्कि एब्स्ट्रक्शन लेयर के रूप में इसके ऊपर काम करता है। आंतरिक आर्किटेक्चर में एनोटेशन प्रोसेसर, कोड जनरेटर और कनेक्शन पूल शामिल हैं। संकलन समय पर, एनोटेशन प्रोसेसर Entity, DAO और Database क्लास का विश्लेषण करता है, फिर _Impl प्रत्यय के साथ इम्प्लीमेंटेशन क्लास जनरेट करता है। सभी जनरेटेड क्लास बिल्ड पैकेज में रखी जाती हैं और सीधे डेवलपर को दिखाई नहीं देती हैं।
संकलन समय पर कोड जनरेशन Room की केंद्रीय तंत्र है। प्रत्येक DAO इंटरफ़ेस के लिए, सभी एनोटेटेड विधियों के पूर्ण कार्यान्वयन वाला एक क्लास जनरेट किया जाता है। @Query एनोटेशन से SQL क्वेरी की शुद्धता के लिए जाँच की जाती है: प्रोसेसर कॉलम नामों को Entity फ़ील्ड से मिलाता है और SQL सिंटैक्स की जाँच करता है। यदि कोई त्रुटि पाई जाती है, तो बिल्ड एक स्पष्ट संदेश के साथ बाधित हो जाता है। यह कच्चे SQLiteOpenHelper का उपयोग करते समय संभव नहीं है, जहाँ त्रुटियाँ केवल रनटाइम पर ही दिखाई देती हैं।
जनरेशन प्रक्रिया में तीन चरण शामिल हैं। पहला — स्कीमा वैलिडेशन: प्रोसेसर जाँचता है कि @Database में सूचीबद्ध सभी क्लास मान्य Entities हैं। दूसरा — DAO बॉडी जनरेशन: प्रत्येक विधि के लिए, आंतरिक RoomSQLiteQuery ऑब्जेक्ट का उपयोग करके एक कार्यान्वयन बनाया जाता है जो प्रिपेयर्ड क्वेरी निष्पादित करता है। तीसरा — Database_Impl क्लास का जनरेशन, जो डेटाबेस निर्माण और खोलने के साथ-साथ सभी DAO ऑब्जेक्ट के आरंभीकरण को संभालता है।
class UserDao_Impl(private val __db: RoomDatabase) : UserDao {
private val __insertionAdapter = __db
.createInsertionAdapter(User::class, 0)
override suspend fun insert(user: User): Long {
__db.assertNotSuspendingTransaction()
return __db.runInTransaction {
__insertionAdapter.insertAndReturnId(user)
}
}
}
Room डेटाबेस संचालन के लिए एक अलग थ्रेड पूल नहीं बनाता है। डिफ़ॉल्ट रूप से, क्वेरी कॉल करने वाले थ्रेड पर एक सीमा के साथ निष्पादित होती हैं: पढ़ना और लिखना थ्रेड को ब्लॉक करता है। एसिंक्रोनस कार्य के लिए, Room Kotlin कोरूटीन के साथ सस्पेंड फंक्शन के माध्यम से, LiveData के साथ रिटर्न वैल्यू के माध्यम से, और Flow के साथ रिएक्टिव रैपर के माध्यम से एकीकृत होता है। यह डेवलपर को किसी विशिष्ट कार्य के लिए आर्किटेक्चरल समाधान चुनने की लचीलापन देता है।
आइए Room का उपयोग करके नोट्स स्टोर करने वाले एप्लिकेशन बनाने का एक व्यावहारिक उदाहरण देखें। एप्लिकेशन में id, title, content और timestamp फ़ील्ड के साथ एक Note तालिका है। उपयोगकर्ता नोट्स जोड़, देख और हटा सकते हैं। एसिंक्रोनस संचालन के लिए कोरूटीन का उपयोग किया जाता है।
Android प्रोजेक्ट में Room को एकीकृत करने के लिए, मॉड्यूल-स्तरीय build.gradle फ़ाइल में निर्भरताएँ जोड़ें। Room को तीन घटकों की आवश्यकता है: रनटाइम लाइब्रेरी, kapt एनोटेशन प्रोसेसर और वैकल्पिक कोरूटीन समर्थन। लाइब्रेरी संस्करण आसान अपडेट के लिए room_version वेरिएबल में निर्दिष्ट किया जाता है। Room 2.4.0 से शुरू करके, तेज़ बिल्ड गति के साथ kapt के विकल्प के रूप में KSP समर्थित है।
dependencies {
def room_version = "2.6.1"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
// वैकल्पिक: परीक्षण
testImplementation "androidx.room:room-testing:$room_version"
}
निर्भरताएँ सेट करने के बाद, तीन फ़ाइलें बनाएँ: Note Entity, NoteDao इंटरफ़ेस और AppDatabase क्लास। Note Entity में @PrimaryKey और @ColumnInfo एनोटेशन वाले फ़ील्ड हैं। DAO इन्सर्ट, सूची प्राप्त करने और डिलीट करने के लिए विधियाँ प्रदान करता है। Database @Database एनोटेशन के माध्यम से Entity और DAO को जोड़ता है।
@Entity(tableName = "notes")
data class Note(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
val title: String,
val content: String,
@ColumnInfo(name = "created_at")
val timestamp: Long = System.currentTimeMillis()
)
@Dao
interface NoteDao {
@Insert
suspend fun insert(note: Note)
@Query("SELECT * FROM notes ORDER BY created_at DESC")
fun getAllNotes(): Flow<List<Note>>
@Delete
suspend fun delete(note: Note)
}
AppDatabase फ़ाइल को RoomDatabase का विस्तार करने वाले एब्स्ट्रैक्ट क्लास के रूप में घोषित किया जाता है। @Database एनोटेशन वर्तमान संस्करण के लिए सभी Entities और स्कीमा संस्करण संख्या निर्दिष्ट करता है। इंस्टेंस प्राप्त करने के लिए, ऐप कॉन्टेक्स्ट के साथ Room.databaseBuilder के build विधि के माध्यम से सिंगलटन पैटर्न का उपयोग किया जाता है। डेटाबेस इंस्टेंस को कैश करना कई निर्माणों को रोकता है जो मेमोरी लीक का कारण बन सकते हैं।
माइग्रेशन Room में मौजूदा डेटा को खोए बिना एप्लिकेशन अपडेट करते समय डेटाबेस स्कीमा बदलने का एक तंत्र है। जब उपयोगकर्ता संशोधित Entities के साथ एक नया संस्करण इंस्टॉल करता है, तो Room संस्करण बेमेल का पता लगाता है और निर्दिष्ट माइग्रेशन चरणों को निष्पादित करता है। माइग्रेशन के बिना, डेटाबेस हटा दिया जाएगा और पुनः बनाया जाएगा, जिसके परिणामस्वरूप सभी उपयोगकर्ता-सहेजे गए डेटा का नुकसान होगा।
माइग्रेशन का वर्णन Migration क्लास द्वारा किया जाता है, जो डेटाबेस के आरंभिक और अंतिम संस्करण लेता है। migrate विधि के अंदर, स्कीमा बदलने के लिए ALTER TABLE या CREATE TABLE SQL क्वेरी निष्पादित की जाती है। Room स्वचालित रूप से स्कीमा परिवर्तनों का पता नहीं लगा सकता — डेवलपर को प्रत्येक Entity परिवर्तन के लिए मैन्युअल रूप से माइग्रेशन लिखना होगा। Room 2.4.0 से शुरू करके, स्वचालित माइग्रेशन जनरेशन के लिए प्रयोगात्मक autoMigrations सुविधा उपलब्ध है।
autoMigrations सुविधा Room को Entity संस्करणों के बीच अंतर के आधार पर स्वचालित रूप से माइग्रेशन जनरेट करने की अनुमति देती है। इसका उपयोग करने के लिए, @Database में @AutoMigration एनोटेशन जोड़ना और JSON में स्कीमा निर्यात सक्षम करना पर्याप्त है। Room आसन्न संस्करणों की स्कीमा की तुलना करता है और आवश्यक ALTER क्वेरी जनरेट करता है। हालाँकि, autoMigrations केवल पिछड़े-संगत परिवर्तनों का समर्थन करता है: कॉलम जोड़ना, इंडेक्स बनाना और संगत परिवर्तनों के साथ प्रकार बदलना।
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL(
"ALTER TABLE users ADD COLUMN phone TEXT"
)
}
}
val db = Room
.databaseBuilder(context, AppDatabase::class.java, "app-db")
.addMigrations(MIGRATION_1_2)
.build()
जटिल परिवर्तनों के लिए, जैसे कॉलम का नाम बदलना या तालिकाओं को मर्ज करना, मध्यवर्ती तालिकाओं का उपयोग करके मैन्युअल माइग्रेशन की आवश्यकता होती है। एक विशिष्ट परिदृश्य: पुरानी स्कीमा के साथ एक अस्थायी तालिका बनाएँ, पुरानी तालिका से नई में परिवर्तनों के साथ डेटा कॉपी करें, पुरानी तालिका हटाएँ और अस्थायी का नाम बदलें। Room गारंटी देता है कि सभी माइग्रेशन एक ही लेन-देन में निष्पादित होते हैं, और यदि कोई त्रुटि होती है, तो परिवर्तन पूरी तरह से वापस ले लिए जाते हैं।
अक्सर पूछे जाने वाले प्रश्न
Room एनोटेशन और संकलन समय पर SQL वैलिडेशन के साथ ORM एब्स्ट्रक्शन प्रदान करता है, जबकि SQLiteOpenHelper को सभी क्वेरी मैन्युअल रूप से लिखने और कनेक्शन प्रबंधित करने की आवश्यकता होती है। Room स्वचालित रूप से CRUD संचालन के लिए कोड जनरेट करता है और Android आर्किटेक्चर घटकों, जिसमें LiveData और Flow शामिल हैं, के साथ एकीकृत होता है।
Room सभी Java आदिम प्रकारों का समर्थन करता है: Int, Long, Boolean, Float, Double, साथ ही String, ByteArray और Date। List या Enum जैसे जटिल प्रकारों के लिए, TypeConverters का उपयोग किया जाता है — स्थैतिक रूपांतरण विधियाँ जो गैर-मानक प्रकारों को SQLite-संगत प्रारूपों में परिवर्तित करती हैं।
हाँ, Room कोरूटीन के बिना सिंक्रोनस कॉल का समर्थन करता है, लेकिन वे उस थ्रेड को ब्लॉक करते हैं जिस पर वे चलते हैं। एसिंक्रोनस कार्य के लिए, आप कोरूटीन के बजाय LiveData या RxJava का उपयोग कर सकते हैं। Google नई परियोजनाओं में एसिंक्रोनस डेटा एक्सेस के प्राथमिक तरीके के रूप में कोरूटीन का उपयोग करने की सलाह देता है।
यदि Room डेटाबेस संस्करण बेमेल का पता लगाता है और उपयुक्त माइग्रेशन नहीं पाता है, तो डिफ़ॉल्ट रूप से यह त्रुटि विवरण के साथ एक IllegalStateException फेंकता है। डेवलपर fallbackToDestructiveMigration विधि के साथ इस व्यवहार को ओवरराइड कर सकता है, जो मौजूदा डेटाबेस को हटा देगा और सभी डेटा खोते हुए एक नया बनाएगा।
Room @Embedded एनोटेशन के साथ नेस्टेड ऑब्जेक्ट और @Relation एनोटेशन के साथ संबंध क्लास के माध्यम से संबंधों का समर्थन करता है। तालिका जॉइन वाले जटिल क्वेरी के लिए, कस्टम POJO क्लास का उपयोग किया जाता है, जिनके फ़ील्ड SQL JOIN स्टेटमेंट के साथ @Query के परिणामों से भरे जाते हैं।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें