रूम परसिस्टेंस लाइब्रेरी, SQLite पर एक ऐब्स्ट्रक्शन लेयर उपलब्ध कराती है, ताकि ताकि SQLite की पूरी क्षमता का इस्तेमाल किया जा सके और डेटाबेस को ज़्यादा बेहतर तरीके से ऐक्सेस किया जा सके. यह यह पेज, Kotlin Multiplatform (KMP) प्रोजेक्ट में रूम के इस्तेमाल पर फ़ोकस करता है. ज़्यादा के लिए रूम का इस्तेमाल करने के बारे में जानकारी, रूम का इस्तेमाल करके स्थानीय डेटाबेस में डेटा सेव करना देखें या हमारे आधिकारिक सैंपल.
डिपेंडेंसी सेट अप करना
रूम का मौजूदा वर्शन जो केएमपी पर काम करता है यह है 2.7.0-alpha01 या इसके बाद का वर्शन.
अपने केएमपी प्रोजेक्ट में रूम सेटअप करने के लिए,
build.gradle.kts
फ़ाइल:
androidx.room:room-gradle-plugin
- रूम स्कीमा को कॉन्फ़िगर करने के लिए Gradle प्लग इनandroidx.room:room-compiler
- KSP का प्रोसेसर, जो कोड जनरेट करता हैandroidx.room:room-runtime
- लाइब्रेरी का रनटाइम हिस्साandroidx.sqlite:sqlite-bundled
- (ज़रूरी नहीं) बंडल की गई SQLite लाइब्रेरी
इसके अलावा, आपको रूम का SQLite ड्राइवर कॉन्फ़िगर करना होगा. ये ड्राइवर अलग-अलग होते हैं टारगेट प्लैटफ़ॉर्म के हिसाब से तय किया जाता है. यहां जाएं: Driver लागू करना देखें.
सेटअप से जुड़ी अतिरिक्त जानकारी के लिए, इन्हें देखें:
- रूम Gradle प्लग इन का इस्तेमाल करके स्कीमा की जगह सेट करना.
- KSP के साथ Kotlin मल्टीप्लैटफ़ॉर्म.
- रनटाइम डिपेंडेंसी जोड़ना.
डेटाबेस क्लास के बारे में जानकारी
आपको डीएओ के साथ-साथ, @Database
से जुड़ी जानकारी देने वाली डेटाबेस क्लास बनानी होगी
और इकाइयां, जो आपके शेयर किए गए केएमपी मॉड्यूल के कॉमन सोर्स सेट में मौजूद हैं. स्थान
ये क्लास सामान्य सोर्स में मौजूद हैं. इन्हें सभी टारगेट के लिए शेयर किया जा सकेगा
प्लैटफ़ॉर्म.
जब इंटरफ़ेस की मदद से, expect
ऑब्जेक्ट का एलान किया जाता है
RoomDatabaseConstructor
, रूम कंपाइलर actual
जनरेट करता है
लागू करना. Android Studio चेतावनी जारी कर सकता है
"Expected object 'AppDatabaseConstructor' has no actual declaration in
module"
; आप @Suppress("NO_ACTUAL_FOR_EXPECT")
का इस्तेमाल करके चेतावनी को छिपा सकते हैं.
// shared/src/commonMain/kotlin/Database.kt
@Database(entities = [TodoEntity::class], version = 1)
@ConstructedBy(AppDatabaseConstructor::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun getDao(): TodoDao
}
// The Room compiler generates the `actual` implementations.
@Suppress("NO_ACTUAL_FOR_EXPECT")
expect object AppDatabaseConstructor : RoomDatabaseConstructor<AppDatabase> {
override fun initialize(): AppDatabase
}
@Dao
interface TodoDao {
@Insert
suspend fun insert(item: TodoEntity)
@Query("SELECT count(*) FROM TodoEntity")
suspend fun count(): Int
@Query("SELECT * FROM TodoEntity")
fun getAllAsFlow(): Flow<List<TodoEntity>>
}
@Entity
data class TodoEntity(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
val title: String,
val content: String
)
ध्यान दें कि आपके पास असल / किए गए एलानों का इस्तेमाल करने का विकल्प होता है
अलग-अलग प्लैटफ़ॉर्म के हिसाब से रूम लागू करने के लिए. उदाहरण के लिए, आप
प्लैटफ़ॉर्म के हिसाब से डीएओ, जिसे expect
का इस्तेमाल करके सामान्य कोड में तय किया जाता है. इसके बाद
प्लैटफ़ॉर्म के हिसाब से, अन्य क्वेरी के साथ actual
की परिभाषाएं बताता है
सोर्स सेट का इस्तेमाल करें.
डेटाबेस बिल्डर बनाना
हर प्लैटफ़ॉर्म पर रूम को इंस्टैंशिएट करने के लिए, आपको डेटाबेस बिल्डर तय करना होगा. यह
एपीआई का सिर्फ़ एक हिस्सा है, जिसका प्लैटफ़ॉर्म के हिसाब से सोर्स में होना ज़रूरी है
सेट हैं. उदाहरण के लिए, Android में,
डेटाबेस की लोकेशन को आम तौर पर
Context.getDatabasePath()
एपीआई, जबकि iOS के लिए डेटाबेस की लोकेशन
पाने के लिए NSFileManager
का इस्तेमाल करें.
Android
डेटाबेस इंस्टेंस बनाने के लिए, डेटाबेस के साथ कॉन्टेक्स्ट तय करें पाथ.
// shared/src/androidMain/kotlin/Database.kt
fun getDatabaseBuilder(ctx: Context): RoomDatabase.Builder<AppDatabase> {
val appContext = ctx.applicationContext
val dbFile = appContext.getDatabasePath("my_room.db")
return Room.databaseBuilder<AppDatabase>(
context = appContext,
name = dbFile.absolutePath
)
}
iOS
डेटाबेस इंस्टेंस बनाने के लिए, इसका इस्तेमाल करके डेटाबेस पाथ दें
NSFileManager
, आम तौर पर NSDocumentDirectory
में मौजूद होता है.
// shared/src/iosMain/kotlin/Database.kt
fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
val dbFilePath = documentDirectory() + "/my_room.db"
return Room.databaseBuilder<AppDatabase>(
name = dbFilePath,
)
}
private fun documentDirectory(): String {
val documentDirectory = NSFileManager.defaultManager.URLForDirectory(
directory = NSDocumentDirectory,
inDomain = NSUserDomainMask,
appropriateForURL = null,
create = false,
error = null,
)
return requireNotNull(documentDirectory?.path)
}
JVM (डेस्कटॉप)
डेटाबेस इंस्टेंस बनाने के लिए, Java या Kotlin का इस्तेमाल करके डेटाबेस का पाथ दें एपीआई.
// shared/src/jvmMain/kotlin/Database.kt
fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
val dbFile = File(System.getProperty("java.io.tmpdir"), "my_room.db")
return Room.databaseBuilder<AppDatabase>(
name = dbFile.absolutePath,
)
}
डेटाबेस इंस्टैंशिएट करना
आपको किसी खास प्लैटफ़ॉर्म से RoomDatabase.Builder
मिलने के बाद
कंस्ट्रक्टर के तौर पर, आपके पास रूम के बाकी डेटाबेस को कॉमन कोड में कॉन्फ़िगर करने की सुविधा होती है
के साथ-साथ.
// shared/src/commonMain/kotlin/Database.kt
fun getRoomDatabase(
builder: RoomDatabase.Builder<AppDatabase>
): AppDatabase {
return builder
.addMigrations(MIGRATIONS)
.fallbackToDestructiveMigrationOnDowngrade()
.setDriver(BundledSQLiteDriver())
.setQueryCoroutineContext(Dispatchers.IO)
.build()
}
SQLiteDriver चुनना
पिछले कोड स्निपेट, BundledSQLiteDriver
का इस्तेमाल करते हैं. यह है
सुझाया गया ड्राइवर जिसमें सोर्स से इकट्ठा की गई SQLite शामिल है, जो
सभी प्लैटफ़ॉर्म पर SQLite का सबसे सटीक और अप-टू-डेट वर्शन होना चाहिए. अगर आपको
अगर आपको ओएस से मिलने वाले SQLite का इस्तेमाल करना है, तो प्लैटफ़ॉर्म के हिसाब से setDriver
एपीआई का इस्तेमाल करें
जो प्लैटफ़ॉर्म के हिसाब से ड्राइवर तय करते हैं. Android के लिए
AndroidSQLiteDriver
, जबकि iOS के लिए NativeSQLiteDriver
का इस्तेमाल किया जा सकता है. यहां की यात्रा पर हूं
NativeSQLiteDriver
का इस्तेमाल करते हैं, तो आपको लिंकर विकल्प देना होगा, ताकि iOS
ऐप्लिकेशन, सिस्टम SQLite से डाइनैमिक तौर पर लिंक करता है.
// shared/build.gradle.kts
kotlin {
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "TodoApp"
isStatic = true
// Required when using NativeSQLiteDriver
linkerOpts.add("-lsqlite3")
}
}
}
अंतर
रूम को मूल रूप से Android लाइब्रेरी के तौर पर बनाया गया था और बाद में एपीआई के साथ काम करने की सुविधा पर फ़ोकस करने वाली KMP. Room का KMP वर्शन कुछ हद तक अलग है अलग-अलग प्लैटफ़ॉर्म के बीच तुलना करता है. ये अंतर नीचे दिए गए निर्देशों का पालन करें.
डीएओ फ़ंक्शन को ब्लॉक करना
केएमपी के लिए रूम का इस्तेमाल करते समय, Android के अलावा अन्य प्लैटफ़ॉर्म के लिए इकट्ठा किए गए सभी डीएओ फ़ंक्शन
reऐक्टिव रिटर्न टाइप को छोड़कर, suspend
फ़ंक्शन होने चाहिए, जैसे कि
Flow
के तौर पर.
// shared/src/commonMain/kotlin/MultiplatformDao.kt
@Dao
interface MultiplatformDao {
// ERROR: Blocking function not valid for non-Android targets
@Query("SELECT * FROM Entity")
fun blockingQuery(): List<Entity>
// OK
@Query("SELECT * FROM Entity")
suspend fun query(): List<Entity>
// OK
@Query("SELECT * FROM Entity")
fun queryFlow(): Flow<List<Entity>>
// ERROR: Blocking function not valid for non-Android targets
@Transaction
fun blockingTransaction() { // … }
// OK
@Transaction
suspend fun transaction() { // … }
}
बेहतरीन एसिंक्रोनस kotlinx.coroutines
लाइब्रेरी का इस्तेमाल करके, कमरे के फ़ायदे
जो Kotlin की मदद से कई प्लैटफ़ॉर्म को ऑफ़र करती है. बेहतर तरीके से काम करने के लिए, suspend
केएमपी प्रोजेक्ट में इकट्ठा किए गए डीएओ के लिए, फ़ंक्शन लागू किए जाते हैं. हालांकि, अपवाद के तौर पर ये सुविधाएं लागू नहीं होती हैं
Android के लिए खास डीएओ, जिन्हें मौजूदा वर्शन के साथ पुराने सिस्टम के साथ काम करने की सुविधा को बनाए रखने के लिए इस्तेमाल किया जाता है
कोड बेस में एक्सपोर्ट करें.
केएमपी की सुविधाओं में अंतर
इस सेक्शन में बताया गया है कि KMP और Android प्लैटफ़ॉर्म के लिए सुविधाएं किस तरह से अलग हैं रूम के वर्शन उपलब्ध हैं.
@RawQuery डीएओ फ़ंक्शन
@RawQuery
के साथ एनोटेट किए गए ऐसे फ़ंक्शन जिन्हें Android के अलावा, दूसरे प्लैटफ़ॉर्म के लिए इकट्ठा किया जाता है
इसके बजाय, RoomRawQuery
टाइप का पैरामीटर बताने की ज़रूरत होगी
SupportSQLiteQuery
.
@Dao
interface TodoDao {
@RawQuery
suspend fun getTodos(query RoomRawQuery): List<TodoEntity>
}
इसके बाद, रनटाइम के दौरान क्वेरी बनाने के लिए RoomRawQuery
का इस्तेमाल किया जा सकता है:
suspend fun getTodosWithLowercaseTitle(title: String): List<TodoEntity> {
val query = RoomRawQuery(
sql = "SELECT * FROM TodoEntity WHERE title = ?"
onBindStatement = {
it.bindText(1, title.lowercase())
}
)
return todosDao.getTodos(query)
}
क्वेरी कॉलबैक
क्वेरी कॉलबैक कॉन्फ़िगर करने के लिए, ये एपीआई सामान्य तौर पर उपलब्ध नहीं हैं इसलिए, यह सुविधा Android के अलावा, किसी भी अन्य प्लैटफ़ॉर्म पर उपलब्ध नहीं है.
RoomDatabase.Builder.setQueryCallback
RoomDatabase.QueryCallback
हम रूम के आने वाले वर्शन में, क्वेरी कॉलबैक के लिए सहायता जोड़ना चाहते हैं.
क्वेरी कॉलबैक के साथ RoomDatabase
को कॉन्फ़िगर करने का एपीआई
कॉलबैक इंटरफ़ेस के साथ RoomDatabase.Builder.setQueryCallback
RoomDatabase.QueryCallback
समान रूप से उपलब्ध नहीं हैं और इसलिए उपलब्ध नहीं हैं
Android के अलावा, अन्य प्लैटफ़ॉर्म पर लागू होते हैं.
अपने-आप बंद होने का डेटाबेस
एक टाइम आउट के बाद, अपने-आप बंद होने की सुविधा चालू करने वाला एपीआई,
RoomDatabase.Builder.setAutoCloseTimeout
, सिर्फ़ Android पर उपलब्ध है और
अन्य प्लैटफ़ॉर्म में उपलब्ध नहीं है.
प्री-पैकेज डेटाबेस
मौजूदा डेटाबेस का इस्तेमाल करके RoomDatabase
बनाने के लिए, नीचे दिए गए एपीआई (जैसे कि
प्री-पैकेज्ड डेटाबेस) समान रूप से उपलब्ध नहीं हैं और इसलिए
की सुविधा मिलती है. ये एपीआई हैं:
RoomDatabase.Builder.createFromAsset
RoomDatabase.Builder.createFromFile
RoomDatabase.Builder.createFromInputStream
RoomDatabase.PrepackagedDatabaseCallback
हम पहले से पैकेज किए गए डेटाबेस के लिए समर्थन को इसके भविष्य के वर्शन में जोड़ना चाहते हैं कमरा.
एक से ज़्यादा इंस्टेंस अमान्य करना
एक से ज़्यादा इंस्टेंस अमान्य होने की सुविधा को चालू करने के लिए एपीआई,
RoomDatabase.Builder.enableMultiInstanceInvalidation
सिर्फ़ यहां उपलब्ध है
Android, आम तौर पर इस्तेमाल किए जाने वाले या किसी दूसरे प्लैटफ़ॉर्म पर उपलब्ध नहीं है.