La libreria androidx.sqlite contiene interfacce astratte e implementazioni di base che possono essere utilizzate per creare le tue librerie che accedono a SQLite. Ti consigliamo di utilizzare la libreria Room, che fornisce un livello di astrazione su SQLite per consentire un accesso più efficace al database, sfruttando al contempo tutta la potenza di SQLite.
Configura le dipendenze
Per configurare SQLite nel tuo progetto KMP, aggiungi le dipendenze per gli artefatti nel file build.gradle.kts del tuo modulo:
[versions]
sqlite = "2.7.1"
[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" }
API SQLite Driver
I gruppi di librerie androidx.sqlite offrono API di basso livello per comunicare con la libreria SQLite inclusa nella libreria quando utilizzi androidx.sqlite:sqlite-bundled o nella piattaforma host, ad esempio Android o iOS, quando utilizzi androidx.sqlite:sqlite-framework. Le API seguono da vicino la funzionalità di base dell'API SQLite C.
Esistono tre interfacce principali:
SQLiteDriver: il punto di accesso a SQLite, utilizzato per aprire le connessioni al database.SQLiteConnection: rappresenta l'oggettosqlite3.SQLiteStatement: rappresenta l'oggettosqlite3_stmt.
L'esempio seguente mostra le API principali:
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() }
Analogamente alle API C di SQLite, il pattern di utilizzo comune prevede i seguenti passaggi:
- Apri una connessione al database utilizzando l'implementazione
SQLiteDriverdi cui è stata creata un'istanza. - Prepara un'istruzione SQL utilizzando
SQLiteConnection.prepare. - Esegui un
SQLiteStatementnel seguente modo:- (Facoltativo) Associa gli argomenti utilizzando le funzioni
bind*. - Esegui l'iterazione sul set di risultati utilizzando la funzione
step. - Leggi le colonne dal set di risultati utilizzando le funzioni
get*.
- (Facoltativo) Associa gli argomenti utilizzando le funzioni
Implementazioni dei driver
La tabella seguente riassume le implementazioni dei driver disponibili:
Nome corso |
Artefatto |
Piattaforme supportate |
AndroidSQLiteDriver |
androidx.sqlite:sqlite-framework |
Android |
NativeSQLiteDriver |
androidx.sqlite:sqlite-framework |
iOS, Mac e Linux |
BundledSQLiteDriver |
androidx.sqlite:sqlite-bundled |
Android, iOS, Mac, Linux e JVM (desktop) |
WebWorkerSQLiteDriver |
androidx.sqlite:sqlite-web |
JavaScript e WebAssembly (WasmJS) |
L'implementazione consigliata da utilizzare è BundledSQLiteDriver, disponibile in androidx.sqlite:sqlite-bundled. Include la libreria SQLite compilata dal codice sorgente, offrendo la versione più aggiornata e la coerenza su tutte le piattaforme KMP supportate.
Driver SQLite e Room
Le API del driver sono utili per le interazioni di basso livello con un database SQLite. Per una libreria ricca di funzionalità che fornisce un accesso più efficace a SQLite, ti consigliamo Room.
Un RoomDatabase si basa su un SQLiteDriver per eseguire le operazioni del database e devi configurare un'implementazione utilizzando RoomDatabase.Builder.setDriver. Room fornisce
RoomDatabase.useReaderConnection e
RoomDatabase.useWriterConnection per un accesso più diretto alle connessioni al database
gestite.
Esegui la migrazione a Kotlin Multiplatform
Devi eseguire la migrazione di qualsiasi utilizzo dei componenti API SQLite di assistenza di basso livello, come l'interfaccia SupportSQLiteDatabase, ai componenti del driver SQLite equivalenti.
Multipiattaforma Kotlin
Esegui una transazione utilizzando SQLiteConnection di basso livello
val connection: SQLiteConnection = BundledSQLiteDriver().open("todos.db") connection.execSQL("BEGIN IMMEDIATE TRANSACTION") try { // perform database operations in transaction. connection.execSQL("END TRANSACTION") } catch (t: Throwable) { connection.execSQL("ROLLBACK TRANSACTION") }
Esegui una query senza risultati
val connection: SQLiteConnection = BundledSQLiteDriver().open("todos.db") connection.execSQL("ALTER TABLE ...")
Esegui una query con un risultato, ma senza argomenti
val connection: SQLiteConnection = BundledSQLiteDriver().open("todos.db") connection.prepare("SELECT * FROM Pet").use { statement -> while (statement.step()) { // read columns. statement.getInt(0) statement.getText(1) } }
Esegui una query con risultati e argomenti
connection.prepare("SELECT * FROM Pet WHERE id = ?").use { statement -> statement.bindInt(1, id) if (statement.step()) { // row found, read columns. } else { // row not found. } }
Solo Android
Esegui una transazione utilizzando SupportSQLiteDatabase
val database: SupportSQLiteDatabase = ...
database.beginTransaction()
try {
// perform database operations in transaction
database.setTransactionSuccessful()
} finally {
database.endTransaction()
}
Esegui una query senza risultati
val database: SupportSQLiteDatabase = ...
database.execSQL("ALTER TABLE ...")
Esegui una query con un risultato, ma senza argomenti
val database: SupportSQLiteDatabase = ...
database.query("SELECT * FROM Pet").use { cursor ->
while (cursor.moveToNext()) {
// read columns
cursor.getInt(0)
cursor.getString(1)
}
}
Esegui una query con risultati e argomenti
database.query("SELECT * FROM Pet WHERE id = ?", id).use { cursor ->
if (cursor.moveToNext()) {
// row found, read columns
} else {
// row not found
}
}