La biblioteca androidx.sqlite contiene interfaces abstractas junto con implementaciones básicas que se pueden usar para compilar tus propias bibliotecas que acceden a SQLite. Se recomienda que consideres usar la biblioteca de Room, que brinda
una capa de abstracción para SQLite que permite acceder a la base de datos sin problemas y, al mismo tiempo,
aprovechar toda la potencia de SQLite.
Configura dependencias
Para configurar SQLite en tu proyecto de KMP, agrega las dependencias de los artefactos en el archivo build.gradle.kts de tu módulo:
[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" }
APIs de controlador de SQLite
Los grupos de bibliotecas androidx.sqlite ofrecen APIs de bajo nivel para comunicarse con la biblioteca de SQLite, ya sea incluida en la biblioteca cuando se usa androidx.sqlite:sqlite-bundled o en la plataforma host, como Android o iOS, cuando se usa androidx.sqlite:sqlite-framework. Las APIs siguen de cerca la funcionalidad principal de la API de SQLite en C.
Existen tres interfaces principales:
SQLiteDriver: Es el punto de entrada a SQLite, que se usa para abrir conexiones de bases de datos.SQLiteConnection: Representa el objetosqlite3.SQLiteStatement: Representa el objetosqlite3_stmt.
En el siguiente ejemplo, se muestran las APIs principales:
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()
}
Al igual que con las APIs en C de SQLite, el patrón de uso común consta de estos pasos:
- Abrir una conexión de base de datos con la implementación de
SQLiteDriverque se creó - Preparar una sentencia de SQL con
SQLiteConnection.prepare - Ejecutar un
SQLiteStatementde la siguiente manera:- Opcional: Vincular argumentos con las funciones
bind* - Iterar el conjunto de resultados con la función
step - Leer columnas del conjunto de resultados con las funciones
get*
- Opcional: Vincular argumentos con las funciones
Implementaciones de controladores
En la siguiente tabla, se resumen las implementaciones de controladores disponibles:
Nombre de clase |
Artefacto |
Plataformas compatibles |
AndroidSQLiteDriver |
androidx.sqlite:sqlite-framework |
Android |
NativeSQLiteDriver |
androidx.sqlite:sqlite-framework |
iOS, Mac y Linux |
BundledSQLiteDriver |
androidx.sqlite:sqlite-bundled |
Android, iOS, Mac, Linux y JVM (computadoras) |
WebWorkerSQLiteDriver |
androidx.sqlite:sqlite-web |
JavaScript y WebAssembly (WasmJS) |
La implementación recomendada para usar es BundledSQLiteDriver, disponible en androidx.sqlite:sqlite-bundled. Incluye la biblioteca de SQLite compilada desde la fuente, que ofrece la versión más actualizada y coherencia en todas las plataformas de KMP compatibles.
Controlador de SQLite y Room
Las APIs de controlador son útiles para las interacciones de bajo nivel con una base de datos SQLite. Para obtener una biblioteca con muchas funciones que proporcione un acceso más sólido a SQLite, te recomendamos Room.
Una RoomDatabase depende de un SQLiteDriver para realizar operaciones de bases de datos,
y debes configurar una implementación con
RoomDatabase.Builder.setDriver. Room provides
RoomDatabase.useReaderConnection and
RoomDatabase.useWriterConnection for more direct access to the managed
database connections.
Migra a Kotlin multiplataforma
Debes migrar cualquier uso de componentes de la API de SQLite de Support de bajo nivel, como la interfaz SupportSQLiteDatabase, a los componentes equivalentes del controlador de SQLite.
Kotlin multiplataforma
Realiza una transacción con SQLiteConnection de bajo nivel
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")
}
Ejecuta una consulta sin resultado
val connection: SQLiteConnection = ...
connection.execSQL("ALTER TABLE ...")
Ejecuta una consulta con resultado, pero sin argumentos
val connection: SQLiteConnection = ...
connection.prepare("SELECT * FROM Pet").use { statement ->
while (statement.step()) {
// read columns
statement.getInt(0)
statement.getText(1)
}
}
Ejecuta una consulta con resultado y argumentos
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 para Android
Realiza una transacción con SupportSQLiteDatabase
val database: SupportSQLiteDatabase = ...
database.beginTransaction()
try {
// perform database operations in transaction
database.setTransactionSuccessful()
} finally {
database.endTransaction()
}
Ejecuta una consulta sin resultado
val database: SupportSQLiteDatabase = ...
database.execSQL("ALTER TABLE ...")
Ejecuta una consulta con resultado, pero sin argumentos
val database: SupportSQLiteDatabase = ...
database.query("SELECT * FROM Pet").use { cursor ->
while (cursor.moveToNext()) {
// read columns
cursor.getInt(0)
cursor.getString(1)
}
}
Ejecuta una consulta con resultado y argumentos
database.query("SELECT * FROM Pet WHERE id = ?", id).use { cursor ->
if (cursor.moveToNext()) {
// row found, read columns
} else {
// row not found
}
}