ตั้งค่า SQLite สำหรับ KMP

ไลบรารี androidx.sqlite มีอินเทอร์เฟซแบบนามธรรมพร้อมกับการใช้งานพื้นฐาน ซึ่งสามารถใช้เพื่อสร้างไลบรารีของคุณเองที่เข้าถึง SQLite ได้ คุณอาจต้องพิจารณาใช้ไลบรารี Room ซึ่งมี เลเยอร์การแยกข้อมูลเหนือ SQLite เพื่อให้เข้าถึงฐานข้อมูลได้อย่างมีประสิทธิภาพมากขึ้น พร้อมทั้งใช้ประโยชน์จากความสามารถทั้งหมดของ SQLite

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

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

[versions] sqlite = "2.5.2"  [libraries] # The SQLite Driver interfaces androidx-sqlite = { module = "androidx.sqlite:sqlite", version.ref = "sqlite" }  # The bundled SQLite driver implementation androidx-sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" }  [plugins] ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } 

SQLite Driver APIs

กลุ่มไลบรารี androidx.sqlite มี API ระดับต่ำสำหรับการสื่อสารกับไลบรารี SQLite ซึ่งรวมอยู่ในไลบรารีเมื่อใช้ androidx.sqlite:sqlite-bundled หรือในแพลตฟอร์มโฮสต์ เช่น Android หรือ iOS เมื่อใช้ androidx.sqlite:sqlite-framework API ทำงานตามฟังก์ชันหลักของ SQLite C API อย่างใกล้ชิด

โดยมีอินเทอร์เฟซหลัก 3 อย่างดังนี้

  • SQLiteDriver - เป็นจุดแรกเข้าในการใช้ SQLite และมีหน้าที่ เปิดการเชื่อมต่อฐานข้อมูล
  • SQLiteConnection - คือการแสดงออบเจ็กต์ sqlite3
  • SQLiteStatement - คือการแสดงออบเจ็กต์ sqlite3_stmt

ตัวอย่างต่อไปนี้แสดง API หลัก

fun main() {   val databaseConnection = BundledSQLiteDriver().open("todos.db")   databaseConnection.execSQL(     "CREATE TABLE IF NOT EXISTS Todo (id INTEGER PRIMARY KEY, content TEXT)"   )   databaseConnection.prepare(     "INSERT OR IGNORE INTO Todo (id, content) VALUES (? ,?)"   ).use { stmt ->     stmt.bindInt(index = 1, value = 1)     stmt.bindText(index = 2, value = "Try Room in the KMP project.")     stmt.step()   }   databaseConnection.prepare("SELECT content FROM Todo").use { stmt ->     while (stmt.step()) {       println("Action item: ${stmt.getText(0)}")     }   }   databaseConnection.close() } 

การใช้งานทั่วไปจะคล้ายกับ SQLite C API ดังนี้

  • เปิดการเชื่อมต่อฐานข้อมูลโดยใช้SQLiteDriver การใช้งานที่สร้างอินสแตนซ์
  • เตรียมคำสั่ง SQL โดยใช้ SQLiteConnection.prepare()
  • เรียกใช้ SQLiteStatement โดยทำดังนี้
    1. คุณเลือกผูกอาร์กิวเมนต์โดยใช้ฟังก์ชัน bind*() หรือไม่ก็ได้
    2. วนซ้ำชุดผลลัพธ์โดยใช้ฟังก์ชัน step()
    3. อ่านคอลัมน์จากชุดผลลัพธ์โดยใช้ฟังก์ชัน get*()

การใช้งานไดรเวอร์

ตารางต่อไปนี้สรุปการใช้งานไดรเวอร์ที่มี

ชื่อชั้นเรียน

อาร์ติแฟกต์

แพลตฟอร์มที่รองรับ

AndroidSQLiteDriver androidx.sqlite:sqlite-framework

Android

NativeSQLiteDriver androidx.sqlite:sqlite-framework

iOS, Mac และ Linux

BundledSQLiteDriver androidx.sqlite:sqlite-bundled

Android, iOS, Mac, Linux และ JVM (เดสก์ท็อป)

การใช้งานที่แนะนำคือ BundledSQLiteDriver ซึ่งมีอยู่ใน androidx.sqlite:sqlite-bundled ซึ่งรวมถึงไลบรารี SQLite ที่คอมไพล์จาก แหล่งที่มา โดยมีเวอร์ชันล่าสุดและมีความสอดคล้องกันในแพลตฟอร์ม KMP ที่รองรับทั้งหมด

ไดรเวอร์ SQLite และ Room

API ไดรเวอร์มีประโยชน์สำหรับการโต้ตอบระดับต่ำกับฐานข้อมูล SQLite หากต้องการคลังที่มีฟีเจอร์มากมายซึ่งให้การเข้าถึง SQLite ที่มีประสิทธิภาพมากขึ้น เราขอแนะนำให้ใช้ Room

RoomDatabase อาศัย SQLiteDriver ในการดำเนินการฐานข้อมูล และต้องกำหนดค่าการติดตั้งใช้งานโดยใช้ RoomDatabase.Builder.setDriver() Room มี RoomDatabase.useReaderConnection และ RoomDatabase.useWriterConnection เพื่อให้เข้าถึงการเชื่อมต่อฐานข้อมูลที่มีการจัดการได้โดยตรงมากขึ้น

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

การใช้งานคอมโพเนนต์ API ของ SQLite ระดับต่ำ (เช่น อินเทอร์เฟซ SupportSQLiteDatabase) ต้องได้รับการย้ายข้อมูลไปยังคอมโพเนนต์ไดรเวอร์ SQLite ที่เทียบเท่า

Kotlin Multiplatform

ทำธุรกรรมโดยใช้ SQLiteConnection ระดับต่ำ

val connection: SQLiteConnection = ... connection.execSQL("BEGIN IMMEDIATE TRANSACTION") try {   // perform database operations in transaction   connection.execSQL("END TRANSACTION") } catch(t: Throwable) {   connection.execSQL("ROLLBACK TRANSACTION") } 

เรียกใช้การค้นหาที่ไม่มีผลลัพธ์

val connection: SQLiteConnection = ... connection.execSQL("ALTER TABLE ...") 

เรียกใช้การค้นหาที่มีผลลัพธ์แต่ไม่มีอาร์กิวเมนต์

val connection: SQLiteConnection = ... connection.prepare("SELECT * FROM Pet").use { statement ->   while (statement.step()) {     // read columns     statement.getInt(0)     statement.getText(1)   } } 

เรียกใช้การค้นหาที่มีผลลัพธ์และอาร์กิวเมนต์

connection.prepare("SELECT * FROM Pet WHERE id = ?").use { statement ->   statement.bindInt(1, id)   if (statement.step()) {     // row found, read columns   } else {     // row not found   } } 

Android เท่านั้น

ทำธุรกรรมโดยใช้ SupportSQLiteDatabase

val database: SupportSQLiteDatabase = ... database.beginTransaction() try {   // perform database operations in transaction   database.setTransactionSuccessful() } finally {   database.endTransaction() } 

เรียกใช้การค้นหาที่ไม่มีผลลัพธ์

val database: SupportSQLiteDatabase = ... database.execSQL("ALTER TABLE ...") 

เรียกใช้การค้นหาที่มีผลลัพธ์แต่ไม่มีอาร์กิวเมนต์

val database: SupportSQLiteDatabase = ... database.query("SELECT * FROM Pet").use { cursor ->   while (cusor.moveToNext()) {     // read columns     cursor.getInt(0)     cursor.getString(1)   } } 

เรียกใช้การค้นหาที่มีผลลัพธ์และอาร์กิวเมนต์

database.query("SELECT * FROM Pet WHERE id = ?", id).use { cursor ->   if (cursor.moveToNext()) {     // row found, read columns   } else {     // row not found   } }