Die androidx.sqlite-Bibliothek enthält abstrakte Schnittstellen sowie grundlegende Implementierungen, mit denen Sie eigene Bibliotheken erstellen können, die auf SQLite zugreifen. Sie sollten die Verwendung der Room-Bibliothek in Betracht ziehen. Sie bietet eine Abstraktionsschicht für SQLite, die einen robusteren Datenbankzugriff ermöglicht und gleichzeitig die volle Leistungsfähigkeit von SQLite nutzt.
Abhängigkeiten einrichten
Wenn Sie SQLite in Ihrem KMP-Projekt einrichten möchten, fügen Sie die Abhängigkeiten für die Artefakte in die Datei build.gradle.kts für Ihr Modul ein:
[versions]
sqlite = "2.6.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-Treiber-APIs
Die androidx.sqlite-Bibliotheksgruppen bieten APIs auf niedriger Ebene für die Kommunikation mit der SQLite-Bibliothek, die entweder in der Bibliothek enthalten ist, wenn androidx.sqlite:sqlite-bundled verwendet wird, oder auf der Hostplattform, z. B. Android oder iOS, wenn androidx.sqlite:sqlite-framework verwendet wird. Die APIs orientieren sich eng an der Kernfunktionalität der SQLite C-API.
Es gibt drei Hauptschnittstellen:
SQLiteDriver: Dies ist der Einstiegspunkt für die Verwendung von SQLite und für das Öffnen von Datenbankverbindungen zuständig.SQLiteConnection: die Darstellung dessqlite3-Objekts.SQLiteStatement: die Darstellung dessqlite3_stmt-Objekts.
Im folgenden Beispiel werden die wichtigsten APIs vorgestellt:
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()
}
Ähnlich wie bei den SQLite C-APIs wird in der Regel so vorgegangen:
- Öffnen Sie eine Datenbankverbindung mit der instanziierten
SQLiteDriver-Implementierung. - SQL-Anweisung mit
SQLiteConnection.prepare()vorbereiten - So führen Sie eine
SQLiteStatementaus:- Optional können Sie Argumente mit den
bind*()-Funktionen binden. - Iterieren Sie mit der Funktion
step()über das Ergebnis-Set. - Lesen Sie Spalten aus dem Ergebnis-Set mit den
get*()-Funktionen.
- Optional können Sie Argumente mit den
Treiberimplementierungen
In der folgenden Tabelle sind die verfügbaren Treiberimplementierungen zusammengefasst:
Kursname |
Artefakt |
Unterstützte Plattformen |
AndroidSQLiteDriver |
androidx.sqlite:sqlite-framework |
Android |
NativeSQLiteDriver |
androidx.sqlite:sqlite-framework |
iOS, Mac und Linux |
BundledSQLiteDriver |
androidx.sqlite:sqlite-bundled |
Android, iOS, Mac, Linux und JVM (Desktop) |
Die empfohlene Implementierung ist BundledSQLiteDriver, die in androidx.sqlite:sqlite-bundled verfügbar ist. Sie enthält die aus dem Quellcode kompilierte SQLite-Bibliothek, die die aktuellste Version und Konsistenz auf allen unterstützten KMP-Plattformen bietet.
SQLite-Treiber und Room
Die Treiber-APIs sind für Low-Level-Interaktionen mit einer SQLite-Datenbank nützlich. Wenn Sie eine funktionsreiche Bibliothek benötigen, die einen robusteren Zugriff auf SQLite bietet, ist Room die richtige Wahl.
Für einen RoomDatabase ist ein SQLiteDriver erforderlich, um Datenbankvorgänge auszuführen. Eine Implementierung muss mit RoomDatabase.Builder.setDriver() konfiguriert werden. Room bietet RoomDatabase.useReaderConnection und RoomDatabase.useWriterConnection für einen direkteren Zugriff auf die verwalteten Datenbankverbindungen.
Zu Kotlin Multiplatform migrieren
Die Verwendung von Support SQLite API-Komponenten auf niedriger Ebene (z. B. die SupportSQLiteDatabase-Schnittstelle) muss zu den entsprechenden SQLite-Treiberkomponenten migriert werden.
Kotlin Multiplatform
Transaktion mit Low-Level-SQLiteConnection ausführen
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")
}
Abfrage ohne Ergebnis ausführen
val connection: SQLiteConnection = ...
connection.execSQL("ALTER TABLE ...")
Eine Abfrage mit Ergebnis, aber ohne Argumente ausführen
val connection: SQLiteConnection = ...
connection.prepare("SELECT * FROM Pet").use { statement ->
while (statement.step()) {
// read columns
statement.getInt(0)
statement.getText(1)
}
}
Eine Abfrage mit Ergebnis und Argumenten ausführen
connection.prepare("SELECT * FROM Pet WHERE id = ?").use { statement ->
statement.bindInt(1, id)
if (statement.step()) {
// row found, read columns
} else {
// row not found
}
}
Nur Android
Transaktion mit SupportSQLiteDatabase durchführen
val database: SupportSQLiteDatabase = ...
database.beginTransaction()
try {
// perform database operations in transaction
database.setTransactionSuccessful()
} finally {
database.endTransaction()
}
Abfrage ohne Ergebnis ausführen
val database: SupportSQLiteDatabase = ...
database.execSQL("ALTER TABLE ...")
Eine Abfrage mit Ergebnis, aber ohne Argumente ausführen
val database: SupportSQLiteDatabase = ...
database.query("SELECT * FROM Pet").use { cursor ->
while (cusor.moveToNext()) {
// read columns
cursor.getInt(0)
cursor.getString(1)
}
}
Eine Abfrage mit Ergebnis und Argumenten ausführen
database.query("SELECT * FROM Pet WHERE id = ?", id).use { cursor ->
if (cursor.moveToNext()) {
// row found, read columns
} else {
// row not found
}
}