כדי למנוע משאילתות לחסום את ממשק המשתמש, אפליקציית Room לא מאפשרת גישה למסד נתונים בשרשור הראשי. המשמעות של ההגבלה הזו היא שאתם צריכים לבצע את הפעולות הבאות: DAO שאילתות אסינכרוניות. החדר כוללת שילובים עם כמה מסגרות שונות כדי לספק ביצוע שאילתה אסינכרונית.
שאילתות DAO מחולקות לשלוש קטגוריות:
- שאילתות כתיבה מדוגמה אחת שמוסיפה, מעדכנות או מוחקים נתונים למסד הנתונים.
- שאילתות קריאה חד-פעמית שקוראות נתונים מהמסד נתונים רק פעם אחת ומחזירות תוצאה עם תמונת המצב של המסד נתונים באותו זמן.
- שאילתות קריאה שניתנת לצפייה שקוראות נתונים ממסד הנתונים שלכם בכל פעם בטבלאות של מסדי הנתונים הבסיסיים משתנים ופולטים ערכים חדשים שישקפו אותם שינויים.
אפשרויות שפה ומסגרות
חדר כולל תמיכה בשילוב ליכולת פעולה הדדית עם שפה ספציפית חדשות וספריות. בטבלה הבאה מפורטים הסוגים הרלוונטיים של החזרת מוצרים, לפי לפי סוג השאילתה והמסגרת:
סוג השאילתה | תכונות של שפת Kotlin | RxJava | גויאבה | Jetpack Lifecycle |
---|---|---|---|---|
כתיבה מהירה | קורוטינים (suspend ) |
Single<T> , Maybe<T>
Completable |
ListenableFuture<T> |
לא רלוונטי |
קריאה חד-פעמית | קורוטינים (suspend ) |
Single<T> , Maybe<T> |
ListenableFuture<T> |
לא רלוונטי |
קריאה גלויה | Flow<T> |
Flowable<T> , Publisher<T>
Observable<T> |
לא רלוונטי | LiveData<T> |
במדריך הזה מוצגות שלוש דרכים אפשריות לשימוש בשילובים האלה כדי להטמיע שאילתות אסינכרוניות ב-DAOs.
קוטלין עם זרימה וקורטינים
Kotlin עם תכונות שפה שמאפשרות לכתוב שאילתות אסינכרוניות ללא מסגרות של צד שלישי:
- בחדר 2.2 ואילך אפשר להשתמש ב-Kotlin זרימה לכתיבת שאילתות שניתנות למדידה.
- בחדר 2.1 ואילך, ניתן להשתמש במילת המפתח
suspend
כדי ליצור את DAO של שאילתות אסינכרוניות באמצעות קורוטינים של Kotlin.
Java עם RxJava
אם באפליקציה שלכם נעשה שימוש בשפת התכנות Java, תוכלו להשתמש בסוגי החזרה מיוחדים מהמסגרת RxJava כדי לכתוב שיטות DAO אסינכרוניות. ב-Room יש תמיכה בסוגי ההחזרים הבאים של RxJava 2:
- לשאילתות מדוגמה אחת, Room 2.1 ואילך תומך
Completable
Single<T>
, ו-Maybe<T>
סוגי החזרה. - עבור שאילתות שניתנות למדידה, Room תומך
Publisher<T>
Flowable<T>
, ו-Observable<T>
סוגי החזרה.
בנוסף, Room 2.3 ואילך תומך ב-RxJava 3.
Java עם LiveData ו-Guava
אם האפליקציה שלכם משתמשת בשפת התכנות Java ואתם לא רוצים להשתמש במסגרת RxJava, אפשר להשתמש בחלופות הבאות כדי לכתוב אסינכרונית שאילתות:
- אפשר להשתמש ב-wrapper של
LiveData
מ-Jetpack לכתיבת שאילתות אסינכרוניות שניתנות לצפייה. - אפשר להשתמש
ListenableFuture<T>
wrapper מ-Guava לכתיבת שאילתות אסינכרוניות חד-פעמיות.
כתיבת שאילתות אסינכרוניות עם דוגמה אחת
שאילתות חד-פעמיות הן פעולות במסד נתונים שפועלות רק פעם אחת ומפיקות קובץ snapshot של הנתונים בזמן הביצוע. ריכזנו כאן כמה דוגמאות לשאילתות חד-פעמיות אסינכרניות:
Kotlin
@Dao interface UserDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertUsers(vararg users: User) @Update suspend fun updateUsers(vararg users: User) @Delete suspend fun deleteUsers(vararg users: User) @Query("SELECT * FROM user WHERE id = :id") suspend fun loadUserById(id: Int): User @Query("SELECT * from user WHERE region IN (:regions)") suspend fun loadUsersByRegion(regions: List<String>): List<User> }
Java
@Dao public interface UserDao { @Insert(onConflict = OnConflictStrategy.REPLACE) public Completable insertUsers(List<User> users); @Update public Completable updateUsers(List<User> users); @Delete public Completable deleteUsers(List<User> users); @Query("SELECT * FROM user WHERE id = :id") public Single<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public Single<List<User>> loadUsersByRegion(List<String> regions); }
Java
@Dao public interface UserDao { // Returns the number of users inserted. @Insert(onConflict = OnConflictStrategy.REPLACE) public ListenableFuture<Integer> insertUsers(List<User> users); // Returns the number of users updated. @Update public ListenableFuture<Integer> updateUsers(List<User> users); // Returns the number of users deleted. @Delete public ListenableFuture<Integer> deleteUsers(List<User> users); @Query("SELECT * FROM user WHERE id = :id") public ListenableFuture<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public ListenableFuture<List<User>> loadUsersByRegion(List<String> regions); }
כתיבת שאילתות שניתנות למדידה
שאילתות שניתן לצפות בהן הן פעולות קריאה שמפיקות ערכים חדשים בכל פעם שיש שינויים באחת מהטבלאות שאלהן מתייחסת השאילתה. אחת הדרכים שבהן אפשר היא יכולה לעזור לכם לשמור על רשימת פריטים מעודכנת כמו הפריטים במסד הנתונים הבסיסי נוספו, עודכנו או הוסרו. ריכזנו כאן כמה דוגמאות לשאילתות שניתן לצפות בהן:
Kotlin
@Dao interface UserDao { @Query("SELECT * FROM user WHERE id = :id") fun loadUserById(id: Int): Flow<User> @Query("SELECT * from user WHERE region IN (:regions)") fun loadUsersByRegion(regions: List<String>): Flow<List<User>> }
Java
@Dao public interface UserDao { @Query("SELECT * FROM user WHERE id = :id") public Flowable<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public Flowable<List<User>> loadUsersByRegion(List<String> regions); }
Java
@Dao public interface UserDao { @Query("SELECT * FROM user WHERE id = :id") public LiveData<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public LiveData<List<User>> loadUsersByRegion(List<String> regions); }
מקורות מידע נוספים
כדי לקבל מידע נוסף על שאילתות DAO אסינכרוניות, אפשר לעיין במקורות הבאים משאבים: