Room 3.0

  
ספריית Room persistence מספקת שכבת הפשטה מעל SQLite כדי לאפשר גישה חזקה יותר למסד הנתונים, תוך ניצול מלוא העוצמה של SQLite.
העדכון האחרון גרסה יציבה גרסה מועמדת להפצה גרסת בטא גרסת אלפא
‫11 במרץ 2026 - - - ‎3.0.0-alpha01

הצהרה על יחסי תלות

כדי להוסיף תלות ב-Room3, צריך להוסיף את מאגר Google Maven לפרויקט. מידע נוסף זמין במאמר בנושא מאגר Maven של Google.

אתם יכולים להוסיף את יחסי התלות של הארטיפקטים שאתם צריכים בקובץ build.gradle של האפליקציה או המודול:

Kotlin

dependencies {
    val room_version = ""

    implementation("androidx.room3:room3-runtime:$room_version")
    ksp("androidx.room3:room3-compiler:$room_version")
}

Groovy

dependencies {
    def room_version = ""

    implementation "androidx.room3:room3-runtime:$room_version"

    ksp "androidx.room3:room3-compiler:$room_version"
}

מידע על השימוש בפלאגין KSP זמין במדריך KSP למתחילים.

מידע נוסף על יחסי תלות זמין במאמר הוספת יחסי תלות ב-build.

שימוש בפלאגין Room Gradle

אפשר להשתמש ב-Room Gradle Plugin כדי להגדיר אפשרויות עבור Room compiler. התוסף מגדיר את הפרויקט כך שהסכימות שנוצרות (שהן פלט של משימות ההידור ומשמשות להעברות אוטומטיות) מוגדרות בצורה נכונה כדי ליצור מבנים שניתן לשחזר ולשמור במטמון.

כדי להוסיף את הפלאגין, מגדירים את הפלאגין ואת הגרסה שלו בקובץ ה-build של Gradle ברמה העליונה.

Groovy

plugins {
    id 'androidx.room3' version "$room_version" apply false
}

Kotlin

plugins {
    id("androidx.room3") version "$room_version" apply false
}

בקובץ build.gradle ברמת המודול, מפעילים את הפלאגין ומשתמשים בתוסף room3.

Groovy

plugins {
    id 'androidx.room3'
}

room3 {
    schemaDirectory "$projectDir/schemas"
}

Kotlin

plugins {
    id("androidx.room3")
}

room3 {
    schemaDirectory("$projectDir/schemas")
}

חובה להגדיר schemaDirectory כשמשתמשים ב-Room Gradle Plugin. הפעולה הזו תגדיר את מהדר Room ואת משימות ההידור השונות ואת הקצוות העורפיים שלו (kotlinc, ‏ KSP) כך שקבצי הסכימה יופקו לתיקיות עם טעמים שונים, לדוגמה schemas/flavorOneDebug/com.package.MyDatabase/1.json. צריך להכניס את הקבצים האלה למאגר כדי להשתמש בהם לאימות ולהעברות אוטומטיות.

משוב

המשוב שלכם עוזר לנו לשפר את Jetpack. נשמח לדעת אם גיליתם בעיות חדשות או אם יש לכם רעיונות איך לשפר את הספרייה הזו. כדאי לעיין בבעיות הידועות בספרייה הזו לפני שמדווחים על בעיה. כדי להוסיף הצבעה בדיווח על בעיה קיימת, לוחצים על כפתור הכוכב.

יצירת דיווח על בעיה חדשה

מידע נוסף זמין במאמרי העזרה בנושא Issue Tracker.

גרסה 3.0

גרסה ‎3.0.0-alpha01

‫11 במרץ 2026

androidx.room3:room3-*:3.0.0-alpha01 מופץ.

‫Room 3.0 (חבילה androidx.room3) הוא עדכון גרסה משמעותי של חבילת Room 2.x (androidx.room) שמתמקד ב-Kotlin Multiplatform‏ (KMP).

ממשקי ה-API העיקריים של ההערות נשארו ללא שינוי, וגם הרכיבים העיקריים:

  • מחלקה מופשטת שמרחיבה את androidx.room3.RoomDatabase ומסומנת ב-@Database היא נקודת הכניסה למעבד אנוטציות (Annotation processor) של Room.
  • בהצהרה על מסד הנתונים יש מחלקה אחת או יותר של נתונים שמתארות את סכימת מסד הנתונים ומסומנות בהערה @Entity.
  • פעולות במסד נתונים מוגדרות בהצהרות @Dao שמכילות פונקציות שאילתה שהצהרות ה-SQL שלהן מוגדרות באמצעות ההערה @Query.
  • בזמן הריצה, אפשר לקבל את ההטמעה של מסד הנתונים באמצעות RoomDatabase.Builder, שמשמש גם להגדרת מסד הנתונים.

רוב התיעוד במדריך שמירת נתונים במסד נתונים מקומי באמצעות Room עדיין רלוונטי ל-Room 3.0.

אלה ההבדלים העיקריים בין גרסה 2.x של Room לגרסה 3.x:

  • חבילה חדשה, androidx.room3.
  • ממשקי ה-API של SupportSQLite לא נתמכים יותר, אלא אם אתם משתמשים ב-androidx.room3:room3-sqlite-wrapper.
  • כל הפעולות במסד הנתונים מבוססות עכשיו על Coroutine APIs.
  • יצירת קוד Kotlin בלבד.
  • נדרש Kotlin Symbol Processing ‏ (KSP).

בנוסף לשינויים שעלולים לשבור את התאימות לאחור, גרסה 3.0 של Room כוללת פונקציונליות חדשה בהשוואה לגרסה 2.x:

  • תמיכה ב-JS וב-WasmJS
  • סוגי החזרה של DAO בהתאמה אישית

חבילה חדשה

כדי למנוע בעיות תאימות עם הטמעות קיימות של Room 2.x ועם ספריות עם יחסי תלות טרנזיטיביים ב-Room (לדוגמה, WorkManager),‏ Room 3.0 נמצא בחבילה חדשה, מה שאומר שיש לו גם מזהי קבוצה וארטיפקט חדשים של Maven. לדוגמה, androidx.room:room-runtime הפך ל-androidx.room3:room3-runtime, ושיעורים כמו androidx.room.RoomDatabase נמצאים עכשיו בכתובת androidx.room3.RoomDatabase.

אין ממשקי API של SupportSQLite

גרסה 3.0 של Room נתמכת באופן מלא על ידי ממשקי ה-API של SQLiteDriver, והיא כבר לא מפנה לסוגים של SupportSQLite כמו SupportSQLiteDatabase או לסוגים של Android כמו Cursor. זהו השינוי המשמעותי ביותר בין גרסה 3.0 לגרסה 2.x של Room, מאז שממשקי ה-API של RoomDatabase ששיקפו את SupportSQLiteDatabase, יחד עם ה-API לקבלת SupportSQLiteOpenHelper, הוסרו. עכשיו SQLiteDriver נדרש כדי ליצור RoomDatabase.

לדוגמה, ממשקי API לפעולות ישירות במסד נתונים מוחלפים במקבילים של מנהלי התקנים:

// Room 2.x
roomDatabase.runInTransaction { ... }

// Room 3.x
roomDatabase.withWriteTransaction { ... }
// Room 2.x
roomDatabase.query("SELECT * FROM Song").use { cursor -> ... }

// Room 3.x
roomDatabase.useReaderConnection { connection ->
  connection.usePrepared("SELECT * FROM Song") { stmt -> ... }
}

ממשקי Callback API שהיה להם ארגומנט SupportSQLiteDatabase הוחלפו גם הם בממשקי API מקבילים עם ארגומנט SQLiteConnection. אלה פונקציות קריאה חוזרת להעברות כמו Migration.onMigrate() ו-AutoMigrationSpec.onPostMigrate(), ופונקציות קריאה חוזרת למסדי נתונים כמו RoomDatabase.Callback.onCreate(), ‏ RoomDatabase.Callback.onOpen() וכו'.

אם נעשה שימוש ב-Room בפרויקט KMP, המעבר לגרסה 3.0 פשוט יותר כי הוא כולל בעיקר עדכון של הפניות לייבוא. אחרת, אותה אסטרטגיית מעבר מ-Room ב-Android בלבד ל-KMP חלה, ראו את מדריך המעבר של Room KMP.

SupportSQLite Wrapper

ב-Room 3.x נשמרת העטיפה SupportSQLite שנוצרה ב-2.x כדי להקל על ההעברות, והיא ממוקמת עכשיו בארטיפקט חדש androidx.room3:room3-sqlite-wrapper. ‫API התאימות מאפשר לכם להמיר RoomDatabase ל-SupportSQLiteDatabase. אפשר להחליף קריאות של roomDatabase.openHelper.writableDatabase בקריאות של roomDatabase.getSupportWrapper().

Kotlin and Coroutines First

כדי לשפר את הספרייה, גרסה Room 3.0 יוצרת רק קוד Kotlin והיא רק מעבד סמלים של Kotlin‏ (KSP). בהשוואה ל-Room 2.x, ב-Room 3.0 אין יצירה של קוד Java, ואי אפשר יותר להגדיר מעבד אנוטציות (Annotation processor) באמצעות KAPT או JavaAP. שימו לב ש-KSP יכול לעבד מקורות Java, והקומפיילר של Room ייצור קוד למסד נתונים, לישויות או ל-DAO שמצהירים על המקור שלהם ב-Java. מומלץ להשתמש בפרויקט מרובה מודולים שבו השימוש ב-Room מרוכז, ואפשר להחיל את Kotlin Gradle Plugin ו-KSP בלי להשפיע על שאר בסיס הקוד.

ב-Room 3.0 גם נדרש שימוש בקורוטינות, ובאופן ספציפי, פונקציות DAO צריכות להיות פונקציות השהיה, אלא אם הן מחזירות סוג תגובתי, כמו Flow או סוג החזרה של DAO בהתאמה אישית. ממשקי API של Room לביצוע פעולות במסד נתונים הם גם פונקציות השהיה, כמו RoomDatabase.useReaderConnection ו-RoomDatabase.useWriterConnection.

בניגוד ל-Room 2.x, אי אפשר יותר להגדיר RoomDatabase עם Executor, אלא אפשר לספק CoroutineContext יחד עם dispatcher באמצעות ה-builder של מסד הנתונים.

ממשקי ה-API ב-Room 3.0 מבוססים על Flow,‏ InvalidationTracker.Observer מוסר יחד עם ממשקי ה-API הרלוונטיים שלו addObserver ו-removeObserver.InvalidationTracker המנגנון להגיב לפעולת מסד נתונים הוא באמצעות Coroutine Flows שאפשר ליצור דרך createFlow() API ב-InvalidationTracker.

דוגמה לשימוש:

fun getArtistTours(from: Date, to: Date): Flow<Map<Artist, TourState>> {
    return db.invalidationTracker.createFlow("Artist").map { _ ->
        val artists = artistsDao.getAllArtists()
        val tours = tourService.fetchStates(artists.map { it.id })
        associateTours(artists, tours, from, to)
    }
}

תמיכה באינטרנט

בגרסה Room 3.0 נוספו JavaScript ו-WasmJs כיעדים של KMP. בנוסף, יצאו ממשקי SQLiteDriver (androidx.sqlite:sqlite) שמטרגטים גם JavaScript ו-WasmJs, וגם דרייבר חדש WebWorkerSQLiteDriver שנמצא בארטיפקט החדש androidx.sqlite:sqlite-web. כך אפשר להשתמש ב-Room בקוד משותף שמטרגט את כל הפלטפורמות העיקריות של KMP.

בגלל האופי האסינכרוני של פלטפורמות האינטרנט, ממשקי Room API שקיבלו את הארגומנט SQLiteStatement הם עכשיו פונקציות השהיה. דוגמאות לפונקציות האלה הן Migration.onMigrate(), RoomDatabase.Callback.onCreate(), PooledConnection.usePrepared() ועוד. בממשקי ה-API של מנהלי ההתקנים, ממשקי ה-API האסינכרוניים נפוצים בכל הפלטפורמות, וממשקי ה-API הסינכרוניים נפוצים ביעדים שאינם באינטרנט. לכן, פרויקט שלא מטרגט את האינטרנט יכול להמשיך להשתמש בממשקי ה-API הסינכרוניים (SQLiteDriver.open(),‏ SQLiteConnection.prepare() ו-SQLiteStatement.step()) בקוד משותף. בינתיים, בפרויקט שמטרגט רק אתרים צריך להשתמש בממשקי ה-API האסינכרוניים (SQLiteDriver.openAsync(), SQLiteConnection.prepareAsync() ו-SQLiteStatement.stepAsync()).

כדי להקל על השימוש, חבילת androidx.sqlite הוסיפה גם פונקציות להשעיית תוספים עם השמות הסינכרוניים של ממשקי ה-API שצוינו (בתוספת SQLiteConnection.executeSQL). מומלץ להשתמש בממשקי ה-API האלה כשהפרויקט מיועד לפלטפורמות אינטרנט ולפלטפורמות אחרות, כי ממשקי ה-API הם הצהרות של ערך צפוי וערך בפועל שיפעילו את הווריאציה הנכונה על סמך הפלטפורמות. אלה ממשקי ה-API שזמן הריצה של Room משתמש בהם, והם מאפשרים שימוש במנהל התקן בקוד משותף לכל הפלטפורמות הנתמכות.

דוגמה לשימוש:

import androidx.sqlite.executeSQL
import androidx.sqlite.step

roomDatabase.useWriterConnection { connection ->
    val deletedSongs = connection.usePrepared(
        "SELECT count(*) FROM Song"
    ) { stmt ->
        stmt.step()
        stmt.getLong(0)
    }
    connection.executeSQL("DELETE FROM Song")
    deletedSongs
}

WebWorkerSQLiteDriver הוא הטמעה של SQLiteDriver שמתקשר עם Web Worker כדי לבצע פעולות במסד הנתונים מחוץ לשרשור הראשי, ומאפשר לאחסן את מסד הנתונים במערכת הקבצים הפרטית של המקור (OPFS). כדי ליצור מופע של ה-driver, צריך worker שמטמיע פרוטוקול תקשורת פשוט. הפרוטוקול מתואר ב-WebWorkerSQLiteDriver KDoc.

בשלב הזה, WebWorkerSQLiteDriver לא מגיע עם worker שמוגדר כברירת מחדל ומיישם את פרוטוקול התקשורת, אבל לדוגמה, בבסיס הקוד של androidx יש יישום של worker שאפשר להשתמש בו בפרויקט. הוא משתמש ב-WASM של SQLite ומאחסן את מסד הנתונים ב-OPFS. ה-worker לדוגמה מתפרסם כחבילת NPM מקומית, ובזכות התמיכה של Kotlin בהסתמכויות על NPM, אפשר ליצור מודול KMP קטן שישמש את ה-worker.

אפשר לעיין בפרויקט GitHub הבא כדי לראות איך משתמשים ב-web worker מקומי ל-Room.

אחרי שמגדירים את העובד בפרויקט, ההגדרה של Room for the Web דומה להגדרה בפלטפורמות אחרות:

fun createDatabase(): MusicDatabase {
    return Room.databaseBuilder<MusicDatabase>("music.db")
        .setDriver(WebWorkerSQLiteDriver(createWorker()))
        .build()
}

fun createWorker() =
    Worker(js("""new URL("sqlite-web-worker/worker.js", import.meta.url)"""))

יכול להיות שגרסה עתידית של Web driver תכיל worker שפורסם ב-NPM כברירת מחדל, וכך תהליך ההגדרה של האינטרנט יהיה פשוט יותר.

סוגי החזרה של DAO בהתאמה אישית

שילובים שונים של סוגי החזרה של DAO, כמו אלה של RxJava ו-Paging, עברו שינוי לשימוש ב-API חדש ב-Room 3.0 שנקרא 'ממירים של סוגי החזרה של DAO'. פונקציית המרה של סוג החזרה של DAO ‏ (@DaoReturnTypeConverter) מאפשרת להמיר את התוצאה של פונקציית DAO לסוג מותאם אישית שמוגדר על ידי הפונקציה עם ההערה. הפונקציות האלה מאפשרות להשתתף בקוד שנוצר ב-Room, שממיר תוצאות של שאילתות לאובייקטים של נתונים. צריך לרשום מחלקות שמכילות המרות של סוגי החזרה של DAO באמצעות ההערות @DaoReturnTypeConverters ב-@Database או בהצהרות @Dao.

לדוגמה, כדי ששאילתת DAO תחזיר PagingSource, צריך לרשום עכשיו את מחלקת ההמרה שנמצאת ב-androidx.room3:room3-paging:

@Dao
@DaoReturnTypeConverters(PagingSourceDaoReturnTypeConverter::class)
interface MusicDao {
    @Query("SELECT * FROM Song)
    fun getSongsPaginated(): PagingSource<Int, Song>
}

השילובים הקיימים הועברו לממירים של סוג ההחזרה של DAO:

סוג הערך שמוחזר סוג המשתמש שביצע המרה פריט מידע שנוצר בתהליך פיתוח (Artifact)
PagingSource PagingSourceDaoReturnTypeConverter androidx.room3:room3-paging
Observable, ‏ Flowable, ‏ Completable, ‏ Single, ‏ Maybe RxDaoReturnTypeConverters androidx.room3:room3-rxjava3
ListenableFuture GuavaDaoReturnTypeConverter androidx.room3:room3-guava
LiveData LiveDataDaoReturnTypeConverter androidx.room3:room3-livedata

בדומה לממירים של סוגי עמודות, אפשר להגדיר ממירים של סוגי החזרה של DAO באמצעות האפליקציה. לדוגמה, אפליקציה יכולה להצהיר על @DaoReturnTypeConverter לסוג האינטרנט kotlin.js.Promise.

object PromiseDaoReturnTypeConverter {
    @DaoReturnTypeConverter([OperationType.READ, OperationType.WRITE])
    fun <T> convert(
        db: RoomDatabase,
        executeAndConvert: suspend () -> T
    ): Promise<T> {
        return db.getCoroutineScope().promise { executeAndConvert() }
    }
}

לאחר מכן, כלי ההמרה שלמעלה מאפשר לפונקציות של שאילתות DAO להחזיר Promise:

@Dao
@DaoReturnTypeConverters(PromiseDaoReturnTypeConverter::class)
interface MusicDao {
    @Query("SELECT * FROM Song")
    fun getAllSongs(): Promise<List<Song>>
}

יש כמה דרישות לגבי פונקציית @DaoReturnTypeConverter, למשל מספר הפרמטרים והסוגים שלהם. הפרמטרים האפשריים הם:

  • db: RoomDatabase: (אופציונלי) מספק גישה למופע RoomDatabase, שיכול להיות שימושי לביצוע פעולות נוספות במסד הנתונים או לגישה להיקף של שגרת המשך (coroutine).
  • tableNames: Array<String>: (אופציונלי) מכיל את הטבלאות שאליהן ניגשים בשאילתה. שימושי לתמיכה בסוגים שניתנים לצפייה או תגובתיים בשילוב עם InvalidationTracker.createFlow() API של Room.
  • rawQuery: RoomRawQuery: (אופציונלי) מכיל בזמן הריצה מופע של השאילתה, שמאפשר טרנספורמציות כמו האסטרטגיה LIMIT / OFFSET שהוטמעה על ידי PagingSourceDaoReturnTypeConverter.
  • executeAndConvert: suspend () -> T: (חובה) הפונקציה שנוצרה על ידי Room שתבצע את השאילתה ותנתח את התוצאה שלה לאובייקטים של נתונים.

מידע נוסף על הדרישות ליצירת ממיר מסוג החזרה של DAO זמין ב-KDoc בנושא @DaoReturnTypeConverterAPI.