כשמשתמשים בספריית Room persistence כדי לאחסן את הנתונים של האפליקציה, מגדירים ישויות שמייצגות את האובייקטים שרוצים לאחסן. כל ישות תואמת לטבלה במסד הנתונים המשויך של Room, וכל מופע של ישות מייצג שורה של נתונים בטבלה התואמת.
שימוש בישויות Room מאפשר להגדיר את סכימת מסד הנתונים בלי לכתוב קוד SQL.
המבנה של ישות
מגדירים כל ישות Room בתור מחלקה עם הערה @Entity. ישות Room כוללת מאפיינים לכל עמודה בטבלה התואמת במסד הנתונים, כולל עמודה אחת או יותר שמרכיבות את המפתח הראשי.
הקוד הבא הוא דוגמה לישות שמגדירה טבלה User עם עמודות למזהה, לשם פרטי ולשם משפחה:
@Entity data class User( @PrimaryKey val id: Int, val firstName: String, val lastName: String )
כברירת מחדל, Room משתמש בשם המחלקה כשם טבלת מסד הנתונים. אם רוצים לתת לטבלה שם אחר, צריך להגדיר את המאפיין tableName של ההערה @Entity. באופן דומה, Room משתמש בשמות המאפיינים כשמות של עמודות במסד הנתונים כברירת מחדל. אם רוצים שלעמודה יהיה שם אחר, מוסיפים את ההערה @ColumnInfo למאפיין ומגדירים את המאפיין name.
בדוגמה הבאה מוצגים שמות בהתאמה אישית לטבלה ולעמודות שלה:
@Entity(tableName = "users") data class User( @PrimaryKey val id: Int, @ColumnInfo(name = "first_name") val firstName: String, @ColumnInfo(name = "last_name") val lastName: String )
הגדרת מפתח ראשי
צריך להגדיר מפתח ראשי לכל ישות של חדר כדי לזהות באופן ייחודי כל שורה בטבלת מסד הנתונים המתאימה. כדי לעשות את זה, מוסיפים הערה לעמודה אחת עם @PrimaryKey:
@PrimaryKey val id: Int
הגדרת מפתח ראשי מורכב
אם אתם צריכים שמופעים של ישות יזוהו באופן ייחודי על ידי שילוב של כמה עמודות, אתם יכולים להגדיר מפתח ראשי מורכב על ידי רישום העמודות האלה במאפיין primaryKeys של @Entity:
@Entity(primaryKeys = ["firstName", "lastName"]) data class User( val firstName: String, val lastName: String )
התעלמות ממאפיינים
כברירת מחדל, Room יוצרת עמודה לכל מאפיין שמוגדר בישות.
כדי למנוע מ-Room לשמור מאפיין, מוסיפים לו את ההערה @Ignore:
@Entity data class User( @PrimaryKey val id: Int, val firstName: String, val lastName: String, @Ignore val picture: Bitmap? = null )
אם ישות יורשת מאפיינים מישות אם, צריך להשתמש במאפיין ignoredColumns של האנוטציה @Entity:
open class User { var picture: Bitmap? = null } @Entity(ignoredColumns = ["picture"]) data class RemoteUser( @PrimaryKey val id: Int, val hasVpn: Boolean ) : User()
מתן תמיכה בחיפוש בטבלה
ב-Room יש כמה הערות שמאפשרות לחפש פרטים בטבלאות של מסד הנתונים.
תמיכה בחיפוש טקסט מלא
אם האפליקציה שלכם דורשת חיפוש מהיר של טקסט מלא (FTS), כדאי לגבות את הישויות באמצעות טבלה וירטואלית. משתמשים בתוסף FTS3 או FTS4 SQLite או בתוסף FTS5 SQLite.
כדי להשתמש ביכולת הזו, מוסיפים את ההערה @Fts3, @Fts4 או @Fts5 לישות.
// Use `@Fts3` only if your app has strict disk space requirements. @Fts4 @Entity(tableName = "users") data class User( // Specifying a primary key for an FTS-table-backed entity is optional, // but if you include one, it must an INTEGER type and column name "rowid". @PrimaryKey @ColumnInfo(name = "rowid") val id: Long, @ColumnInfo(name = "first_name") val firstName: String )
כדי להתאים אישית את האופן שבו מידע ממסד נתונים עובר טוקניזציה בטבלאות FTS, משתמשים באפשרות tokenizer. ספריית Room מספקת כמה טוקנייזרים מובנים דרך FtsOptions, כולל TOKENIZER_SIMPLE, TOKENIZER_PORTER ו-TOKENIZER_UNICODE61:
@Fts4(tokenizer = FtsOptions.TOKENIZER_UNICODE61) @Entity(tableName = "users") data class User( @PrimaryKey @ColumnInfo(name = "rowid") val id: Long, @ColumnInfo(name = "first_name") val firstName: String )
ב-Room יש כמה אפשרויות נוספות להגדרת ישויות שמגובות על ידי FTS, כולל
סידור תוצאות, הסרת אינדקסים מעמודות וטבלאות שמנוהלות כתוכן חיצוני. לקבלת מידע נוסף על האפשרויות האלה, אפשר לעיין במאמר בנושא FtsOptions.
אינדקס של עמודות ספציפיות
אם אתם משתמשים ב-AndroidSQLiteDriver ואתם צריכים לתמוך בגרסאות SDK שלא תומכות בישויות שמגובות בטבלאות FTS3, FTS4 או FTS5, עדיין תוכלו להוסיף לאינדקס עמודות מסוימות במסד הנתונים כדי להאיץ את השאילתות. אם אתם משתמשים ב-BundledSQLiteDriver, Room תומכת בכל גרסאות ה-FTS, ללא קשר לגרסת Android SDK.
כדי להוסיף אינדקסים לישות, צריך לכלול את המאפיין indices בהערה @Entity. מפרטים את שמות העמודות שרוצים לכלול באינדקס או באינדקס מורכב. בקטע הקוד הבא מוצג איך מוסיפים אינדקסים:
@Entity(indices = [Index(value = ["last_name", "address"])]) data class User( @PrimaryKey val id: Int, @ColumnInfo(name = "first_name") val firstName: String, @ColumnInfo(name = "last_name") val lastName: String, val address: String?, )
לפעמים, עמודות מסוימות או קבוצות של עמודות במסד נתונים צריכות להכיל ערכים ייחודיים. כדי לאכוף את הייחודיות הזו, מגדירים את המאפיין unique של הערת @Index לערך true. בדוגמת הקוד הבאה אפשר לראות איך מוודאים שהערך יהיה ייחודי:
@Entity(indices = [Index(value = ["first_name", "last_name"], unique = true)]) data class User( @PrimaryKey val id: Int, @ColumnInfo(name = "first_name") val firstName: String, @ColumnInfo(name = "last_name") val lastName: String, )