הספרייה androidx.sqlite מכילה ממשקים מופשטים וגם יישומים בסיסיים שאפשר להשתמש בהם כדי ליצור ספריות משלכם עם גישה ל-SQLite. אפשר להשתמש בספריית Room, שמספקת שכבת הפשטה מעל SQLite כדי לאפשר גישה חזקה יותר למסד הנתונים, תוך ניצול מלוא היכולות של SQLite.
הגדרת יחסי תלות
כדי להגדיר את SQLite בפרויקט KMP, מוסיפים את יחסי התלות של הארטיפקטים בקובץ build.gradle.kts של המודול:
[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" }
SQLite Driver APIs
קבוצות הספרייה androidx.sqlite מציעות ממשקי API ברמה נמוכה לתקשורת עם ספריית SQLite, שנכללת בספרייה כשמשתמשים ב-androidx.sqlite:sqlite-bundled או בפלטפורמת המארח, כמו Android או iOS כשמשתמשים ב-androidx.sqlite:sqlite-framework. ממשקי ה-API דומים מאוד לפונקציונליות המרכזית של SQLite C API.
יש שלושה ממשקים עיקריים:
-
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 APIs, דפוס השימוש הנפוץ כולל את השלבים הבאים:
- פותחים חיבור למסד נתונים באמצעות ההטמעה של
SQLiteDriverשנוצרה. - מכינים הצהרת SQL באמצעות
SQLiteConnection.prepare. - מריצים
SQLiteStatementבאופן הבא:- אופציונלי: קושרים ארגומנטים באמצעות הפונקציות
bind*. - מבצעים איטרציה על קבוצת התוצאות באמצעות הפונקציה
step. - קוראים עמודות מתוך קבוצת התוצאות באמצעות הפונקציות
get*.
- אופציונלי: קושרים ארגומנטים באמצעות הפונקציות
הטמעות של Driver
בטבלה הבאה מפורטים סוגי הדרייברים הזמינים:
שם הכיתה |
פריט מידע שנוצר בתהליך פיתוח (Artifact) |
פלטפורמות נתמכות |
AndroidSQLiteDriver |
androidx.sqlite:sqlite-framework |
Android |
NativeSQLiteDriver |
androidx.sqlite:sqlite-framework |
iOS, Mac ו-Linux |
BundledSQLiteDriver |
androidx.sqlite:sqlite-bundled |
Android, iOS, Mac, Linux ו-JVM (מחשב) |
WebWorkerSQLiteDriver |
androidx.sqlite:sqlite-web |
JavaScript ו-WebAssembly (WasmJS) |
ההטמעה המומלצת לשימוש היא BundledSQLiteDriver שזמינה ב-androidx.sqlite:sqlite-bundled. היא כוללת את ספריית SQLite שעברה קומפילציה ממקור, ומציעה את הגרסה העדכנית ביותר ועקביות בכל הפלטפורמות הנתמכות של KMP.
SQLite Driver ו-Room
ממשקי ה-API של מנהלי ההתקנים שימושיים לאינטראקציות ברמה נמוכה עם מסד נתונים של SQLite. אם אתם רוצים להשתמש בספרייה עשירה בתכונות שמספקת גישה חזקה יותר ל-SQLite, מומלץ להשתמש ב-Room.
RoomDatabase מסתמך על SQLiteDriver כדי לבצע פעולות במסד הנתונים, ולכן צריך להגדיר הטמעה באמצעות RoomDatabase.Builder.setDriver. Room מספקת RoomDatabase.useReaderConnection ו-RoomDatabase.useWriterConnection לגישה ישירה יותר לחיבורים מנוהלים למסד הנתונים.
העברה ל-Kotlin Multiplatform
צריך להעביר כל שימוש ברכיבי API של SQLite ברמה נמוכה, כמו הממשק SupportSQLiteDatabase, לרכיבי SQLite Driver מקבילים.
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 (cursor.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
}
}