ตั้งค่าฐานข้อมูล Room สำหรับ KMP

ไลบรารี Room Persistence มีเลเยอร์นามธรรมเหนือ SQLite เพื่อให้เข้าถึงฐานข้อมูลได้อย่างมีประสิทธิภาพมากขึ้น พร้อมทั้งใช้ประโยชน์จาก SQLite ได้อย่างเต็มที่ หน้านี้จะเน้นที่การใช้ Room ในโปรเจ็กต์ Kotlin Multiplatform (KMP) ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ Room ได้ที่บันทึกข้อมูลในฐานข้อมูลในเครื่องโดยใช้ Room หรือตัวอย่างอย่างเป็นทางการของเรา

ตั้งค่าทรัพยากร Dependency

หากต้องการตั้งค่า Room ในโปรเจ็กต์ KMP ให้เพิ่มทรัพยากร Dependency สำหรับอาร์ติแฟกต์ในไฟล์ build.gradle.kts สำหรับโมดูล KMP

กำหนดทรัพยากร Dependency ในไฟล์ libs.versions.toml ดังนี้

[versions]
room3 = "3.1.0-alpha03"
sqlite = "2.7.1"
ksp = "<kotlinCompatibleKspVersion>"

[libraries]
androidx-sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" }
androidx-room3-runtime = { module = "androidx.room3:room3-runtime", version.ref = "room3" }
androidx-room3-compiler = { module = "androidx.room3:room3-compiler", version.ref = "room3" }

# Optional SQLite Wrapper
androidx-room3-sqlite-wrapper = { module = "androidx.room3:room3-sqlite-wrapper", version.ref = "room3" }

[plugins]
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
androidx-room3 = { id = "androidx.room3", version.ref = "room3" }

เพิ่มปลั๊กอิน Room Gradle เพื่อกำหนดค่าสคีมา Room และปลั๊กอิน KSP

plugins {
  alias(libs.plugins.ksp)
  alias(libs.plugins.androidx.room3)
}

เพิ่มทรัพยากร Dependency ของรันไทม์ Room และไลบรารี SQLite ที่รวมมาด้วย

commonMain.dependencies {
  implementation(libs.androidx.room3.runtime)
  implementation(libs.androidx.sqlite.bundled)
}

// Optional when using Room SQLite Wrapper
androidMain.dependencies {
  implementation(libs.androidx.room3.sqlite.wrapper)
}

เพิ่มทรัพยากร Dependency ของ KSP ลงในบล็อก dependencies รูท คุณต้องเพิ่มเป้าหมายทั้งหมดที่แอปใช้ ดูข้อมูลเพิ่มเติมได้ที่ KSP กับ Kotlin Multiplatform

dependencies {
    add("kspAndroid", libs.androidx.room3.compiler)
    add("kspIosSimulatorArm64", libs.androidx.room3.compiler)
    add("kspIosX64", libs.androidx.room3.compiler)
    add("kspIosArm64", libs.androidx.room3.compiler)
    // Add any other platform target you use in your project, for example kspDesktop
}

กำหนดไดเรกทอรีสคีมาของห้อง ดูข้อมูลเพิ่มเติมได้ที่ตั้งค่าตำแหน่งสคีมาโดยใช้ปลั๊กอิน Room Gradle

room {
    schemaDirectory("$projectDir/schemas")
}

กำหนดคลาสฐานข้อมูล

คุณต้องสร้างคลาสฐานข้อมูลที่มีคำอธิบายประกอบ @Database พร้อมกับ DAO และเอนทิตีภายในชุดซอร์สทั่วไปของโมดูล KMP ที่แชร์ การวางคลาสเหล่านี้ในแหล่งที่มาทั่วไปจะช่วยให้แชร์คลาสเหล่านี้ในแพลตฟอร์มเป้าหมายทั้งหมดได้

// 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("KotlinNoActualForExpect")
expect object AppDatabaseConstructor : RoomDatabaseConstructor<AppDatabase> {
    override fun initialize(): AppDatabase
}

เมื่อคุณประกาศออบเจ็กต์ expect ด้วยอินเทอร์เฟซ RoomDatabaseConstructor คอมไพเลอร์ Room จะสร้างการติดตั้งใช้งาน actual Android Studio อาจแสดงคำเตือนต่อไปนี้ ซึ่งคุณสามารถระงับได้ด้วย @Suppress("KotlinNoActualForExpect")

Expected object 'AppDatabaseConstructor' has no actual declaration in module`

ถัดไป ให้กำหนดอินเทอร์เฟซ DAO ใหม่หรือย้ายอินเทอร์เฟซที่มีอยู่ไปยัง commonMain ดังนี้

// shared/src/commonMain/kotlin/TodoDao.kt

@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>>
}

กำหนดหรือย้ายเอนทิตีไปยัง commonMain:

// shared/src/commonMain/kotlin/TodoEntity.kt

@Entity
data class TodoEntity(
    @PrimaryKey(autoGenerate = true) val id: Long = 0,
    val title: String,
    val content: String
)

สร้างเครื่องมือสร้างฐานข้อมูลเฉพาะแพลตฟอร์ม

คุณต้องกำหนด Database Builder เพื่อสร้างอินสแตนซ์ Room ในแต่ละแพลตฟอร์ม นี่เป็นส่วนเดียวของ API ที่คุณต้องกำหนดในชุดซอร์สเฉพาะแพลตฟอร์ม เนื่องจาก API ระบบไฟล์มีความแตกต่างกัน

Android

ใน Android โดยปกติแล้วคุณจะได้รับตำแหน่งฐานข้อมูลโดยใช้ API Context.getDatabasePath หากต้องการสร้างอินสแตนซ์ฐานข้อมูล ให้ระบุ Context และเส้นทางฐานข้อมูล

// shared/src/androidMain/kotlin/Database.android.kt

fun getDatabaseBuilder(context: Context): RoomDatabase.Builder<AppDatabase> {
    val appContext = context.applicationContext
    val dbFile = appContext.getDatabasePath("my_room.db")
    return Room.databaseBuilder<AppDatabase>(
        context = appContext,
        name = dbFile.absolutePath
    )
}

iOS

หากต้องการสร้างอินสแตนซ์ฐานข้อมูลใน iOS ให้ระบุเส้นทางฐานข้อมูลโดยใช้ NSFileManager ซึ่งโดยปกติจะอยู่ใน NSDocumentDirectory

// shared/src/iosMain/kotlin/Database.ios.kt

fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
    val dbFilePath = documentDirectory() + "/my_room.db"
    return Room.databaseBuilder<AppDatabase>(
        name = dbFilePath,
    )
}

@OptIn(ExperimentalForeignApi::class)
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 API

// shared/src/jvmMain/kotlin/Database.desktop.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 จากคอนสตรัคเตอร์เฉพาะแพลตฟอร์มแล้ว คุณจะกำหนดค่าฐานข้อมูล Room ที่เหลือในโค้ดทั่วไปพร้อมกับการสร้างอินสแตนซ์ฐานข้อมูลจริงได้

// shared/src/commonMain/kotlin/Database.kt

fun getRoomDatabase(
    builder: RoomDatabase.Builder<AppDatabase>
): AppDatabase {
    return builder
        .setDriver(BundledSQLiteDriver())
        .setQueryCoroutineContext(Dispatchers.IO)
        .build()
}

เลือกไดรเวอร์ SQLite

ข้อมูลโค้ดก่อนหน้าจะเรียกใช้ฟังก์ชัน Builder setDriver เพื่อกำหนดไดรเวอร์ SQLite ที่ฐานข้อมูล Room ควรใช้ ไดรเวอร์เหล่านี้จะแตกต่างกันไปตามแพลตฟอร์มเป้าหมาย ข้อมูลโค้ดก่อนหน้านี้ใช้ BundledSQLiteDriver ซึ่งเป็นไดรเวอร์ที่แนะนำซึ่งมี SQLite ที่คอมไพล์จากแหล่งที่มา ซึ่งให้ SQLite เวอร์ชันที่สอดคล้องและอัปเดตที่สุดในทุกแพลตฟอร์ม

หากต้องการใช้ SQLite ที่ระบบปฏิบัติการมีให้ ให้ใช้ setDriver API ในชุดซอร์สเฉพาะแพลตฟอร์มที่ระบุไดรเวอร์เฉพาะแพลตฟอร์ม ดูคำอธิบายการติดตั้งใช้งานไดรเวอร์ที่ใช้ได้ที่หัวข้อการติดตั้งใช้งานไดรเวอร์ คุณสามารถใช้ตัวเลือกใดตัวเลือกหนึ่งต่อไปนี้

หากต้องการใช้ NativeSQLiteDriver คุณต้องระบุตัวเลือก Linker -lsqlite3 เพื่อให้แอป 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")
        }
    }
}

ตั้งค่าบริบท Coroutine

คุณสามารถกำหนดค่าออบเจ็กต์ RoomDatabase ใน Android ด้วยผู้ดำเนินการแอปพลิเคชันที่แชร์โดยใช้ RoomDatabase.Builder.setQueryExecutor เพื่อดำเนินการฐานข้อมูลได้

เนื่องจาก Executor ไม่เข้ากันกับ KMP API setQueryExecutor ของ Room จึงไม่พร้อมใช้งานใน commonMain แต่ต้องกำหนดค่าออบเจ็กต์ RoomDatabase ด้วย CoroutineContext ซึ่งคุณตั้งค่าได้โดยใช้ RoomDatabase.Builder.setCoroutineContext หากคุณไม่ได้ตั้งค่าบริบท ออบเจ็กต์ RoomDatabase จะมีค่าเริ่มต้นเป็น Dispatchers.IO

การลดขนาดและการสร้างความสับสน

หากโปรเจ็กต์มีการลดขนาดหรือสร้างความสับสน คุณต้องรวมกฎ ProGuard ต่อไปนี้เพื่อให้ Room ค้นหาการติดตั้งใช้งานที่สร้างขึ้นของคำจำกัดความฐานข้อมูลได้

-keep class * extends androidx.room3.RoomDatabase { <init>(); }

ย้ายข้อมูลไปยัง Kotlin Multiplatform

เดิมที Room ได้รับการพัฒนาเป็นไลบรารี Android และต่อมาได้ย้ายข้อมูลไปยัง KMP โดยมุ่งเน้นที่ความเข้ากันได้ของ API Room เวอร์ชัน KMP แตกต่างกันเล็กน้อยระหว่างแพลตฟอร์มและจากเวอร์ชันเฉพาะ Android ความแตกต่างเหล่านี้แสดงและอธิบายไว้ดังนี้

ย้ายข้อมูลจาก Support SQLite ไปยังไดรเวอร์ SQLite

การใช้งาน SupportSQLiteDatabase และ API อื่นๆ ใน androidx.sqlite.db ต้องได้รับการเปลี่ยนโครงสร้างภายในโค้ดด้วย SQLite Driver API เนื่องจาก API ใน androidx.sqlite.db เป็นแบบ Android เท่านั้น (โปรดสังเกตแพ็กเกจที่แตกต่างจากแพ็กเกจ KMP)

เพื่อความเข้ากันได้แบบย้อนหลัง และตราบใดที่มีการกำหนดค่า RoomDatabase ด้วย SupportSQLiteOpenHelper.Factory (เช่น ไม่มีการตั้งค่า SQLiteDriver) Room จะทำงานใน "โหมดความเข้ากันได้" ซึ่งทั้ง Support SQLite และ SQLite Driver API จะทำงานตามที่คาดไว้ ซึ่งจะช่วยให้คุณย้ายข้อมูลแบบค่อยเป็นค่อยไปได้ คุณจึงไม่จำเป็นต้องแปลงการใช้งาน Support SQLite ทั้งหมดเป็นไดรเวอร์ SQLite ในการเปลี่ยนแปลงครั้งเดียว

ใช้ Wrapper ของ Room SQLite

อาร์ติแฟกต์ androidx.room3:room3-sqlite-wrapper มี API เพื่อเชื่อมระหว่าง SQLiteDriver และ SupportSQLiteDatabase ระหว่างการย้ายข้อมูล

หากต้องการรับ SupportSQLiteDatabase จาก RoomDatabase ที่กำหนดค่าด้วย SQLiteDriver ให้ใช้ฟังก์ชันส่วนขยายใหม่ RoomDatabase.getSupportWrapper Wrapper ความเข้ากันได้นี้ช่วยรักษาการใช้งาน SupportSQLiteDatabase ที่มีอยู่ ซึ่งคุณมักจะได้รับจาก RoomDatabase.openHelper.writableDatabase ขณะที่ใช้ SQLiteDriver โดยเฉพาะอย่างยิ่งสำหรับฐานของโค้ดที่มีการใช้งาน SupportSQLite API อย่างกว้างขวางซึ่งต้องการใช้ BundledSQLiteDriver

แปลงคลาสย่อยของการย้ายข้อมูล

ต้องย้ายข้อมูลคลาสย่อยของการย้ายข้อมูลไปยังคู่ที่ตรงกันของไดรเวอร์ SQLite ดังนี้

Kotlin Multiplatform

คลาสย่อยของการย้ายข้อมูล

object Migration_1_2 : Migration(1, 2) {
    override suspend fun migrate(connection: SQLiteConnection) {
        // ...
    }
}

คลาสย่อยของข้อกำหนดการย้ายข้อมูลอัตโนมัติ

class AutoMigrationSpec_1_2 : AutoMigrationSpec {
    override suspend fun onPostMigrate(connection: SQLiteConnection) {
        // ...
    }
}

Android เท่านั้น

คลาสย่อยของการย้ายข้อมูล

object Migration_1_2 : Migration(1, 2) {
  override fun migrate(db: SupportSQLiteDatabase) {
    // …
  }
}

คลาสย่อยของข้อกำหนดการย้ายข้อมูลอัตโนมัติ

class AutoMigrationSpec_1_2 : AutoMigrationSpec {
  override fun onPostMigrate(db: SupportSQLiteDatabase) {
    // …
  }
}

Callback การแปลงฐานข้อมูล

ต้องย้ายข้อมูล Callback ของฐานข้อมูลไปยังไดรเวอร์ SQLite ที่เทียบเท่ากัน ดังนี้

Kotlin Multiplatform

object MyRoomCallback : RoomDatabase.Callback() {
    override suspend fun onCreate(connection: SQLiteConnection) {
        // ...
    }

    override suspend fun onDestructiveMigration(connection: SQLiteConnection) {
        // ...
    }

    override suspend fun onOpen(connection: SQLiteConnection) {
        // ...
    }
}

Android เท่านั้น

object MyRoomCallback : RoomDatabase.Callback() {
  override fun onCreate(db: SupportSQLiteDatabase) {
    // …
  }

  override fun onDestructiveMigration(db: SupportSQLiteDatabase) {
    // …
  }

  override fun onOpen(db: SupportSQLiteDatabase) {
    // …
  }
}

แปลงฟังก์ชัน DAO @RawQuery รายการ

ฟังก์ชันที่มีคำอธิบายประกอบด้วย @RawQuery ซึ่งคอมไพล์สำหรับแพลตฟอร์มที่ไม่ใช่ Android จะต้องประกาศพารามิเตอร์ประเภท RoomRawQuery แทน SupportSQLiteQuery

Kotlin Multiplatform

กำหนดการค้นหาดิบ

@Dao
interface TodoDao {
    @RawQuery
    suspend fun getTodos(query: RoomRawQuery): List<TodoEntity>
}

จากนั้นจะใช้ RoomRawQuery เพื่อสร้างการค้นหาที่รันไทม์ได้ ดังนี้

suspend fun AppDatabase.getTodosWithLowercaseTitle(title: String): List<TodoEntity> {
    val query = RoomRawQuery(
        sql = "SELECT * FROM TodoEntity WHERE title = ?",
        onBindStatement = {
            it.bindText(1, title.lowercase())
        }
    )

    return getDao().getTodos(query)
}

Android เท่านั้น

กำหนดการค้นหาดิบ

@Dao
interface TodoDao {
  @RawQuery
  suspend fun getTodos(query: SupportSQLiteQuery): List<TodoEntity>
}

จากนั้นจะใช้ SimpleSQLiteQuery เพื่อสร้างการค้นหาที่รันไทม์ได้ ดังนี้

suspend fun AndroidOnlyDao.getTodosWithLowercaseTitle(title: String): List<TodoEntity> {
  val query = SimpleSQLiteQuery(
      query = "SELECT * FROM TodoEntity WHERE title = ?",
      bindArgs = arrayOf(title.lowercase())
  )
  return getTodos(query)
}

แปลงฟังก์ชัน DAO ที่บล็อก

Room ได้รับประโยชน์จากไลบรารี kotlinx.coroutines แบบอะซิงโครนัสที่มีฟีเจอร์หลากหลายซึ่ง Kotlin มีให้สำหรับหลายแพลตฟอร์ม เพื่อฟังก์ชันการทำงานที่ดีที่สุด ระบบจะบังคับใช้ฟังก์ชัน suspend สำหรับ DAO ที่คอมไพล์ในโปรเจ็กต์ KMP ยกเว้น DAO ที่ติดตั้งใช้งานใน androidMain เพื่อรักษาความเข้ากันได้แบบย้อนหลังกับฐานของโค้ดที่มีอยู่ เมื่อใช้ Room สำหรับ KMP ฟังก์ชัน DAO ทั้งหมดที่คอมไพล์สำหรับแพลตฟอร์มที่ไม่ใช่ Android จะต้องเป็นฟังก์ชัน suspend

Kotlin Multiplatform

กำลังระงับการค้นหา

@Query("SELECT * FROM Todo")
suspend fun getAllTodos(): List<Todo>

การระงับธุรกรรม

@Transaction
suspend fun transaction() {
    // ...
}

Android เท่านั้น

การค้นหาที่ถูกบล็อก

@Query("SELECT * FROM Todo")
fun getAllTodos(): List<Todo>

การบล็อกธุรกรรม

@Transaction
fun blockingTransaction() { … }

แปลงประเภทรีแอ็กทีฟเป็น Flow

ฟังก์ชัน DAO ทั้งหมดไม่จำเป็นต้องเป็นฟังก์ชันระงับ ไม่ควรแปลงฟังก์ชัน DAO ที่แสดงผลประเภทรีแอ็กทีฟ เช่น LiveData หรือ Flowable ของ RxJava เป็นฟังก์ชันระงับ อย่างไรก็ตาม บางประเภท เช่น LiveData ไม่รองรับ KMP ต้องย้ายข้อมูลฟังก์ชัน DAO ที่มีประเภทการแสดงผลแบบรีแอ็กทีฟไปยังโฟลว์ Coroutine

Kotlin Multiplatform

ประเภทเชิงรับ Flows

@Query("SELECT * FROM Todo")
fun getTodosFlow(): Flow<List<Todo>>

Android เท่านั้น

ประเภท Reactive เช่น LiveData หรือ Flowable ของ RxJava

@Query("SELECT * FROM Todo")
fun getTodosLiveData(): LiveData<List<Todo>>

API ธุรกรรมการแปลง

API ธุรกรรมฐานข้อมูลสำหรับ Room KMP สามารถแยกความแตกต่างระหว่างธุรกรรมการเขียน (useWriterConnection) และการอ่าน (useReaderConnection) ได้

Kotlin Multiplatform

val database: RoomDatabase = getRoomDatabase(builder)
database.useWriterConnection { transactor ->
    transactor.immediateTransaction {
        // perform database operations in transaction.
    }
}

Android เท่านั้น

val database: RoomDatabase = …
database.withTransaction {
  // perform database operations in transaction
}

เขียนธุรกรรม

ใช้ธุรกรรมการเขียนเพื่อให้แน่ใจว่าการค้นหาหลายรายการเขียนข้อมูลแบบอะตอมมิก เพื่อให้ผู้อ่านเข้าถึงข้อมูลได้อย่างสม่ำเสมอ ซึ่งทำได้โดยใช้ useWriterConnection กับธุรกรรมทั้ง 3 ประเภทต่อไปนี้

  • immediateTransaction: ในโหมด Write-Ahead Logging (WAL) (ค่าเริ่มต้น) ธุรกรรมประเภทนี้จะได้รับการล็อกเมื่อเริ่มต้น แต่ผู้อ่านจะยังคงอ่านต่อได้ ซึ่งเป็นตัวเลือกที่แนะนำสำหรับกรณีส่วนใหญ่

  • deferredTransaction: ธุรกรรมจะไม่ได้รับล็อกจนกว่าจะมีคำสั่งเขียนแรก ใช้ธุรกรรมประเภทนี้เป็นการเพิ่มประสิทธิภาพเมื่อคุณไม่แน่ใจว่าจำเป็นต้องมีการดำเนินการเขียนภายในธุรกรรมหรือไม่ ตัวอย่างเช่น หากคุณเริ่มธุรกรรมเพื่อลบเพลงออกจากเพลย์ลิสต์โดยระบุเพียงชื่อเพลย์ลิสต์และเพลย์ลิสต์นั้นไม่มีอยู่ ก็ไม่จำเป็นต้องดำเนินการเขียน (ลบ)

  • exclusiveTransaction: โหมดนี้ทำงานเหมือนกับ immediateTransaction ในโหมด WAL ในโหมดการทำเจอร์นัลอื่นๆ ระบบจะป้องกันไม่ให้การเชื่อมต่อฐานข้อมูลอื่นๆ อ่านฐานข้อมูลขณะที่ธุรกรรมกำลังดำเนินอยู่

อ่านธุรกรรม

ใช้ธุรกรรมการอ่านเพื่ออ่านจากฐานข้อมูลหลายครั้งอย่างสม่ำเสมอ เช่น เมื่อคุณมีคำค้นหาแยกกัน 2 รายการขึ้นไปและไม่ได้ใช้ส่วนคำสั่ง JOIN อนุญาตเฉพาะธุรกรรมที่เลื่อนเวลาออกไปในการเชื่อมต่อผู้อ่าน การพยายามเริ่มธุรกรรมแบบทันทีหรือแบบเอกสิทธิ์เฉพาะบุคคลในการเชื่อมต่อของ Reader จะทำให้เกิดข้อยกเว้น เนื่องจากถือเป็นการดำเนินการ "เขียน"

val database: RoomDatabase = getRoomDatabase(builder)
database.useReaderConnection { transactor ->
    transactor.deferredTransaction {
        // perform database operations in transaction.
    }
}

ไม่พร้อมใช้งานใน Kotlin Multiplatform

API บางรายการที่พร้อมใช้งานสำหรับ Android จะไม่พร้อมใช้งานใน Kotlin Multiplatform

Callback การค้นหา

API ต่อไปนี้สำหรับการกำหนดค่า Callback ของการค้นหาไม่พร้อมใช้งานใน Common จึงไม่พร้อมใช้งานในแพลตฟอร์มอื่นที่ไม่ใช่ Android

  • RoomDatabase.Builder.setQueryCallback
  • RoomDatabase.QueryCallback

ฐานข้อมูลที่ปิดอัตโนมัติ

API สำหรับเปิดใช้การปิดอัตโนมัติหลังจากหมดเวลา RoomDatabase.Builder.setAutoCloseTimeout พร้อมใช้งานใน Android เท่านั้น

ฐานข้อมูลที่จัดทำไว้ล่วงหน้า

API ต่อไปนี้เพื่อสร้าง RoomDatabase โดยใช้ฐานข้อมูลที่มีอยู่ (ฐานข้อมูลที่จัดแพ็กเกจไว้ล่วงหน้า) ไม่พร้อมใช้งานโดยทั่วไป จึงไม่พร้อมใช้งานในแพลตฟอร์มอื่นๆ นอกเหนือจาก Android

  • RoomDatabase.Builder.createFromAsset
  • RoomDatabase.Builder.createFromFile
  • RoomDatabase.Builder.createFromInputStream
  • RoomDatabase.PrepackagedDatabaseCallback

การลบล้างอินสแตนซ์หลายรายการ

API สำหรับเปิดใช้การลบล้างอินสแตนซ์หลายรายการ RoomDatabase.Builder.enableMultiInstanceInvalidation มีให้บริการใน Android เท่านั้น และไม่มีให้บริการในแพลตฟอร์มทั่วไปหรือแพลตฟอร์มอื่นๆ