Biblioteka androidx.sqlite zawiera abstrakcyjne interfejsy oraz podstawowe implementacje, których można używać do tworzenia własnych bibliotek, które mają dostęp do SQLite. Warto rozważyć użycie biblioteki Room, która zapewnia
warstwę abstrakcji nad SQLite, aby umożliwić bardziej niezawodny dostęp do bazy danych przy
jednoczesnym wykorzystaniu pełnej mocy SQLite.
Konfigurowanie zależności
Aby skonfigurować SQLite w projekcie KMP, dodaj zależności artefaktów w pliku build.gradle.kts modułu:
[versions]
sqlite = "2.7.0"
[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" }
Interfejsy API sterownika SQLite
Grupy bibliotek androidx.sqlite oferują interfejsy API niskiego poziomu do komunikacji z
biblioteką SQLite, która jest dołączona do biblioteki w przypadku używania
androidx.sqlite:sqlite-bundled lub na platformie hosta, np. Androida lub iOS,
w przypadku używania androidx.sqlite:sqlite-framework. Interfejsy API ściśle odpowiadają podstawowym funkcjom interfejsu SQLite C API.
Dostępne są 3 główne interfejsy:
SQLiteDriver: punkt wejścia do SQLite, używany do otwierania połączeń z bazą danych.SQLiteConnection: reprezentuje obiektsqlite3.SQLiteStatement: reprezentuje obiektsqlite3_stmt.
Poniższy przykład przedstawia podstawowe interfejsy 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()
}
Podobnie jak w przypadku interfejsów SQLite C API typowy sposób użycia obejmuje te kroki:
- Otwórz połączenie z bazą danych za pomocą utworzonej instancji implementacji
SQLiteDriver. - Przygotuj instrukcję SQL za pomocą
SQLiteConnection.prepare. - Wykonaj
SQLiteStatement, wykonując te czynności:- Opcjonalnie: powiąż argumenty za pomocą funkcji
bind*. - Iteruj po zbiorze wyników za pomocą funkcji
step. - Odczytaj kolumny ze zbioru wyników za pomocą funkcji
get*.
- Opcjonalnie: powiąż argumenty za pomocą funkcji
Implementacje sterowników
W tabeli poniżej znajdziesz podsumowanie dostępnych implementacji sterowników:
Nazwa zajęć |
Artefakt |
Obsługiwane platformy |
AndroidSQLiteDriver |
androidx.sqlite:sqlite-framework |
Android |
NativeSQLiteDriver |
androidx.sqlite:sqlite-framework |
iOS, Mac i Linux |
BundledSQLiteDriver |
androidx.sqlite:sqlite-bundled |
Android, iOS, Mac, Linux i JVM (komputer) |
WebWorkerSQLiteDriver |
androidx.sqlite:sqlite-web |
JavaScript i WebAssembly (WasmJS) |
Zalecana implementacja to BundledSQLiteDriver dostępna w androidx.sqlite:sqlite-bundled. Zawiera ona bibliotekę SQLite skompilowaną ze źródła, która oferuje najnowszą wersję i spójność na wszystkich obsługiwanych platformach KMP.
Sterownik SQLite i Room
Interfejsy API sterowników są przydatne w przypadku interakcji niskiego poziomu z bazą danych SQLite. Jeśli potrzebujesz biblioteki z wieloma funkcjami, która zapewnia bardziej niezawodny dostęp do SQLite, zalecamy użycie Room.
A RoomDatabase korzysta z SQLiteDriver do wykonywania operacji na bazie danych,
a implementację musisz skonfigurować za pomocą
RoomDatabase.Builder.setDriver. Room udostępnia
RoomDatabase.useReaderConnection i
RoomDatabase.useWriterConnection w celu uzyskania bardziej bezpośredniego dostępu do zarządzanych
połączeń z bazą danych.
Migracja do Kotlin Multiplatform
Musisz przeprowadzić migrację wszystkich zastosowań komponentów interfejsu Support SQLite API niskiego poziomu, takich jak interfejs SupportSQLiteDatabase, do odpowiednich komponentów sterownika SQLite.
Kotlin Multiplatform
Wykonaj transakcję za pomocą SQLiteConnection niskiego poziomu
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")
}
Wykonaj zapytanie bez wyniku
val connection: SQLiteConnection = ...
connection.execSQL("ALTER TABLE ...")
Wykonaj zapytanie z wynikiem, ale bez argumentów
val connection: SQLiteConnection = ...
connection.prepare("SELECT * FROM Pet").use { statement ->
while (statement.step()) {
// read columns
statement.getInt(0)
statement.getText(1)
}
}
Wykonaj zapytanie z wynikiem i argumentami
connection.prepare("SELECT * FROM Pet WHERE id = ?").use { statement ->
statement.bindInt(1, id)
if (statement.step()) {
// row found, read columns
} else {
// row not found
}
}
Tylko na Androidzie
Wykonaj transakcję za pomocą SupportSQLiteDatabase
val database: SupportSQLiteDatabase = ...
database.beginTransaction()
try {
// perform database operations in transaction
database.setTransactionSuccessful()
} finally {
database.endTransaction()
}
Wykonaj zapytanie bez wyniku
val database: SupportSQLiteDatabase = ...
database.execSQL("ALTER TABLE ...")
Wykonaj zapytanie z wynikiem, ale bez argumentów
val database: SupportSQLiteDatabase = ...
database.query("SELECT * FROM Pet").use { cursor ->
while (cursor.moveToNext()) {
// read columns
cursor.getInt(0)
cursor.getString(1)
}
}
Wykonaj zapytanie z wynikiem i argumentami
database.query("SELECT * FROM Pet WHERE id = ?", id).use { cursor ->
if (cursor.moveToNext()) {
// row found, read columns
} else {
// row not found
}
}