SQLite (Kotlin Çoklu Platform)

androidx.sqlite kitaplığı, SQLite'e erişen kendi kitaplıklarınızı oluşturmak için kullanılabilecek temel uygulamalarla birlikte soyut arayüzler içerir. SQLite'ın tüm gücünden yararlanırken daha sağlam veritabanı erişimi sağlamak için SQLite üzerinde bir soyutlama katmanı sunan Room kitaplığını kullanmayı düşünebilirsiniz.

Bağımlılıkları ayarlama

KMP projenizde SQLite'ı ayarlamak için modülünüzün build.gradle.kts dosyasındaki yapılarla ilgili bağımlılıkları ekleyin:

[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 API'leri

androidx.sqlite kitaplık grupları, androidx.sqlite:sqlite-bundled kullanılırken kitaplığa dahil edilen veya androidx.sqlite:sqlite-framework kullanılırken Android ya da iOS gibi ana makine platformunda bulunan SQLite kitaplığıyla iletişim kurmak için düşük düzeyli API'ler sunar. API'ler, SQLite C API'nin temel işlevlerini yakından takip eder.

3 ana arayüz vardır:

  • SQLiteDriver: SQLite'ı kullanmak için giriş noktasıdır ve veritabanı bağlantılarını açmaktan sorumludur.
  • SQLiteConnection: sqlite3 nesnesinin gösterimidir.
  • SQLiteStatement: sqlite3_stmt nesnesinin gösterimidir.

Aşağıdaki örnekte temel API'ler gösterilmektedir:

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'lerine benzer şekilde, yaygın kullanım şekli şöyledir:

  • Örneklenmiş SQLiteDriver uygulamasını kullanarak bir veritabanı bağlantısı açın.
  • SQLiteConnection.prepare() kullanarak SQL ifadesi hazırlama
  • Aşağıdaki şekilde bir SQLiteStatement yürütün:
    1. İsteğe bağlı olarak bind*() işlevlerini kullanarak bağımsız değişkenleri bağlayın.
    2. step() işlevini kullanarak sonuç kümesinde yineleme yapın.
    3. get*() işlevlerini kullanarak sonuç kümesindeki sütunları okuyun.

Sürücü Uygulamaları

Aşağıdaki tabloda, kullanılabilir sürücü uygulamaları özetlenmektedir:

Sınıf adı

Yapı

Desteklenen Platformlar

AndroidSQLiteDriver androidx.sqlite:sqlite-framework

Android

NativeSQLiteDriver androidx.sqlite:sqlite-framework

iOS, Mac ve Linux

BundledSQLiteDriver androidx.sqlite:sqlite-bundled

Android, iOS, Mac, Linux ve JVM (Masaüstü)

Kullanılması önerilen uygulama, BundledSQLiteDriver androidx.sqlite:sqlite-bundled içinde kullanılabilir. Kaynak koddan derlenen SQLite kitaplığını içerir. Bu kitaplık, desteklenen tüm KMP platformlarında en güncel sürümü ve tutarlılığı sunar.

SQLite sürücüsü ve Room

Sürücü API'leri, SQLite veritabanıyla düşük düzeyli etkileşimler için kullanışlıdır. SQLite'e daha sağlam bir erişim sağlayan, özellik açısından zengin bir kitaplık için Room önerilir.

Bir RoomDatabase, veritabanı işlemlerini gerçekleştirmek için SQLiteDriver'ye bağlıdır ve RoomDatabase.Builder.setDriver() kullanılarak yapılandırılması gerekir. Room, yönetilen veritabanı bağlantılarına daha doğrudan erişim için RoomDatabase.useReaderConnection ve RoomDatabase.useWriterConnection sağlar.

Kotlin Multiplatform'a geçiş

Düşük düzeydeki SQLite çağrılarının tümü, SQLite sürücülerine taşınmalıdır.

Kotlin Multiplatform

Düşük düzeyli SQLiteConnection kullanarak işlem gerçekleştirme

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")
}

Sonuç vermeyen bir sorgu yürütme

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

Sonuç içeren ancak bağımsız değişken içermeyen bir sorgu yürütme

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

Sonuç ve bağımsız değişken içeren bir sorgu yürütme

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

Yalnızca Android

SupportSQLiteDatabase kullanarak işlem yapma

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

Sonuç vermeyen bir sorgu yürütme

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

Sonuç içeren ancak bağımsız değişken içermeyen bir sorgu yürütme

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

Sonuç ve bağımsız değişken içeren bir sorgu yürütme

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