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. Te recomendamos que uses 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.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" }
APIs del 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 3 interfaces principales:
SQLiteDriver
: Es el punto de entrada para usar SQLite y es responsable de abrir conexiones de bases de datos.SQLiteConnection
: Es la representación del objetosqlite3
.SQLiteStatement
: Es la representación del 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 de C de SQLite, el uso común es el siguiente:
- Abre una conexión de base de datos con la implementación de
SQLiteDriver
que se creó. - Prepara una instrucción de SQL con
SQLiteConnection.prepare()
- Ejecuta un
SQLiteStatement
de la siguiente manera:- De manera opcional, vincula argumentos con las funciones
bind*()
. - Itera el conjunto de resultados con la función
step()
. - Lee columnas del conjunto de resultados con las funciones
get*()
.
- De manera opcional, vincula argumentos con las funciones
Implementaciones de controladores
En la siguiente tabla, se resumen las implementaciones de controladores disponibles:
Nombre de la clase |
Artefacto |
Plataformas admitidas |
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 (escritorio) |
La implementación recomendada para usar es BundledSQLiteDriver
, disponible en androidx.sqlite:sqlite-bundled
. Incluye la biblioteca de SQLite compilada desde la fuente, lo que ofrece la versión más actualizada y coherencia en todas las plataformas de KMP compatibles.
Controlador de SQLite y Room
Las APIs del controlador son útiles para las interacciones de bajo nivel con una base de datos SQLite. Si buscas una biblioteca con muchas funciones que proporcione un acceso más sólido a SQLite, te recomendamos Room.
Un RoomDatabase
depende de un SQLiteDriver
para realizar operaciones de bases de datos, y se requiere una implementación para configurarse con RoomDatabase.Builder.setDriver()
. Room proporciona RoomDatabase.useReaderConnection
y RoomDatabase.useWriterConnection
para un acceso más directo a las conexiones de bases de datos administradas.
Migra a Kotlin Multiplatform
Cualquier uso de llamadas de SQLite de bajo nivel debe migrarse a sus equivalentes de SQLite Driver.
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 resultados
val connection: SQLiteConnection = ...
connection.execSQL("ALTER TABLE ...")
Ejecuta una consulta con un 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 resultados 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
Cómo realizar 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 resultados
val database: SupportSQLiteDatabase = ...
database.execSQL("ALTER TABLE ...")
Ejecuta una consulta con un resultado, pero sin argumentos
val database: SupportSQLiteDatabase = ...
database.query("SELECT * FROM Pet").use { cursor ->
while (cusor.moveToNext()) {
// read columns
cursor.getInt(0)
cursor.getString(1)
}
}
Ejecuta una consulta con resultados y argumentos
database.query("SELECT * FROM Pet WHERE id = ?", id).use { cursor ->
if (cursor.moveToNext()) {
// row found, read columns
} else {
// row not found
}
}