androidx.sqlite 库包含抽象接口和基本实现,可用于构建自己的库来访问 SQLite。您可能要考虑使用 Room 库,它在 SQLite 上提供了一个抽象层,让您能够在充分利用 SQLite 的强大功能的同时,获享更完善的数据库访问机制。
设置依赖项
如需在 KMP 项目中设置 SQLite,请在模块的 build.gradle.kts 文件中添加工件的依赖项:
[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" } SQLite 驱动程序 API
androidx.sqlite 库组提供用于与 SQLite 库通信的低级 API,该库在使用 androidx.sqlite:sqlite-bundled 时包含在库中,在使用 androidx.sqlite:sqlite-framework 时包含在宿主平台(例如 Android 或 iOS)中。这些 API 紧密遵循 SQLite C API 的核心功能。
主要有 3 个接口:
SQLiteDriver- 这是使用 SQLite 的入口点,负责打开数据库连接。SQLiteConnection- 是sqlite3对象的表示形式。SQLiteStatement- 是sqlite3_stmt对象的表示形式。
以下示例展示了核心 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() } 与 SQLite C API 类似,常见用法是:
- 使用实例化的
SQLiteDriver实现打开数据库连接。 - 使用
SQLiteConnection.prepare()准备 SQL 语句 - 以如下方式执行
SQLiteStatement:- 可以选择使用
bind*()函数绑定实参。 - 使用
step()函数迭代结果集。 - 使用
get*()函数从结果集中读取列。
- 可以选择使用
驱动程序实现
下表总结了可用的驱动程序实现:
类名称 | 制品 | 支持的平台 |
AndroidSQLiteDriver | androidx.sqlite:sqlite-framework | Android |
NativeSQLiteDriver | androidx.sqlite:sqlite-framework | iOS、Mac 和 Linux |
BundledSQLiteDriver | androidx.sqlite:sqlite-bundled | Android、iOS、Mac、Linux 和 JVM(桌面设备) |
建议使用的实现是 androidx.sqlite:sqlite-bundled 中提供的 BundledSQLiteDriver。它包含从源代码编译的 SQLite 库,可在所有受支持的 KMP 平台上提供最新版本和一致性。
SQLite 驱动程序和 Room
驱动程序 API 非常适合用于与 SQLite 数据库进行低级别互动。 如果您需要一个功能丰富的库来提供更强大的 SQLite 访问机制,建议使用 Room。
RoomDatabase 依赖于 SQLiteDriver 来执行数据库操作,并且需要使用 RoomDatabase.Builder.setDriver() 配置实现。Room 提供 RoomDatabase.useReaderConnection 和 RoomDatabase.useWriterConnection,以便更直接地访问受管理的数据库连接。
迁移到 Kotlin Multiplatform
对低级支持 SQLite API 组件(例如 SupportSQLiteDatabase 接口)的任何使用都需要迁移到等效的 SQLite 驱动程序组件。
Kotlin Multiplatform
使用低级 SQLiteConnection 执行交易
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") } 执行无结果的查询
val connection: SQLiteConnection = ... connection.execSQL("ALTER TABLE ...") 执行有结果但没有实参的查询
val connection: SQLiteConnection = ... connection.prepare("SELECT * FROM Pet").use { statement -> while (statement.step()) { // read columns statement.getInt(0) statement.getText(1) } } 执行包含结果和实参的查询
connection.prepare("SELECT * FROM Pet WHERE id = ?").use { statement -> statement.bindInt(1, id) if (statement.step()) { // row found, read columns } else { // row not found } } 仅限 Android
使用 SupportSQLiteDatabase 执行交易
val database: SupportSQLiteDatabase = ... database.beginTransaction() try { // perform database operations in transaction database.setTransactionSuccessful() } finally { database.endTransaction() } 执行无结果的查询
val database: SupportSQLiteDatabase = ... database.execSQL("ALTER TABLE ...") 执行有结果但没有实参的查询
val database: SupportSQLiteDatabase = ... database.query("SELECT * FROM Pet").use { cursor -> while (cusor.moveToNext()) { // read columns cursor.getInt(0) cursor.getString(1) } } 执行包含结果和实参的查询
database.query("SELECT * FROM Pet WHERE id = ?", id).use { cursor -> if (cursor.moveToNext()) { // row found, read columns } else { // row not found } }