הגדרת נתונים באמצעות ישויות חדרים

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

המשמעות היא שתוכלו להשתמש בישויות של חדרים כדי להגדיר את מסד הנתונים שלכם. סכימה בלי או לכתוב כל קוד SQL.

המבנה של יישות

אתם מגדירים כל ישות בחדר ככיתה שמסומנת בהערה עם @Entity ישות 'חדר' כוללת לכל עמודה בטבלה המתאימה במסד הנתונים, כולל שדה אחד או יותר עמודות שמהן מורכב המפתח הראשי.

הקוד הבא הוא דוגמה לישות פשוטה שמגדירה את הטבלה User עם עמודות של מזהה, שם פרטי ושם משפחה:

Kotlin

@Entity
data class User(
    @PrimaryKey val id: Int,

    val firstName: String?,
    val lastName: String?
)

Java

@Entity
public class User {
    @PrimaryKey
    public int id;

    public String firstName;
    public String lastName;
}

כברירת מחדל, שם הכיתה משמש את Room בתור שם הטבלה של מסד הנתונים. אם רוצים יהיה שם אחר, הגדירו את tableName של המאפיין הערה @Entity. באופן דומה, שמות השדות משמשים כשמות של עמודות מסד הנתונים כברירת מחדל. כדי לתת לעמודה שם אחר, צריך להוסיף את השם שלה. @ColumnInfo מגדירים את השדה name לנכס. בדוגמה הבאה מוצגים שמות מותאמים אישית של טבלה והעמודות שלה:

Kotlin

@Entity(tableName = "users")
data class User (
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "last_name") val lastName: String?
)

Java

@Entity(tableName = "users")
public class User {
    @PrimaryKey
    public int id;

    @ColumnInfo(name = "first_name")
    public String firstName;

    @ColumnInfo(name = "last_name")
    public String lastName;
}

הגדרה של מפתח ראשי

לכל ישות של חדר צריך להגדיר מפתח ראשי שמזהה באופן ייחודי כל שורה בטבלה המתאימה של מסד הנתונים. במידה הרבה ביותר הדרך הישירה לעשות זאת היא להוסיף הערות לעמודה אחת עם @PrimaryKey:

Kotlin

@PrimaryKey val id: Int

Java

@PrimaryKey
public int id;

הגדרת מפתח ראשי מורכב

אם אתם צריכים שמופעים של ישות יהיו מזוהים באופן ייחודי באמצעות שילוב של מספר עמודות, אפשר להגדיר מפתח ראשי מורכב על ידי פירוט בעמודות primaryKeys מאפיין של @Entity:

Kotlin

@Entity(primaryKeys = ["firstName", "lastName"])
data class User(
    val firstName: String?,
    val lastName: String?
)

Java

@Entity(primaryKeys = {"firstName", "lastName"})
public class User {
    public String firstName;
    public String lastName;
}

התעלמות משדות

כברירת מחדל, החדר יוצר עמודה לכל שדה שמוגדר בישות. אם בישות יש שדות שאתם לא רוצים שיישמרו, אפשר להוסיף להם הערות. באמצעות @Ignore, כמו מוצגת בקטע הקוד הבא:

Kotlin

@Entity
data class User(
    @PrimaryKey val id: Int,
    val firstName: String?,
    val lastName: String?,
    @Ignore val picture: Bitmap?
)

Java

@Entity
public class User {
    @PrimaryKey
    public int id;

    public String firstName;
    public String lastName;

    @Ignore
    Bitmap picture;
}

במקרים שבהם ישות יורשת שדות מישות אם, לרוב היא יורשת קל יותר להשתמש מאפיין ignoredColumns של המאפיין @Entity:

Kotlin

open class User {
    var picture: Bitmap? = null
}

@Entity(ignoredColumns = ["picture"])
data class RemoteUser(
    @PrimaryKey val id: Int,
    val hasVpn: Boolean
) : User()

Java

@Entity(ignoredColumns = "picture")
public class RemoteUser extends User {
    @PrimaryKey
    public int id;

    public boolean hasVpn;
}

יש כמה סוגים של הערות שאפשר להוסיף לחדר כדי שיהיה קל יותר לחפש אותן לפרטים בטבלאות של מסד הנתונים. להשתמש בחיפוש טקסט מלא, אלא אם minSdkVersion קטן מ-16.

תמיכה בחיפוש טקסט מלא

אם לאפליקציה שלך נדרשת גישה מהירה מאוד לפרטי מסד נתונים באמצעות טקסט מלא של חיפוש (FTS), לגבות את הישויות בטבלה וירטואלית שמשתמשת תוסף SQLite ל-FTS3 או FTS4 . כדי להשתמש ביכולת הזו, שזמין בחדר 2.1.0 ומעלה, יש להוסיף את @Fts3 או הערה @Fts4 לישות נתונה, כפי שמוצג בקטע הקוד הבא:

Kotlin

// Use `@Fts3` only if your app has strict disk space requirements or if you
// require compatibility with an older SQLite version.
@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 use this type and column name. */
    @PrimaryKey @ColumnInfo(name = "rowid") val id: Int,
    @ColumnInfo(name = "first_name") val firstName: String?
)

Java

// Use `@Fts3` only if your app has strict disk space requirements or if you
// require compatibility with an older SQLite version.
@Fts4
@Entity(tableName = "users")
public class User {
    // Specifying a primary key for an FTS-table-backed entity is optional, but
    // if you include one, it must use this type and column name.
    @PrimaryKey
    @ColumnInfo(name = "rowid")
    public int id;

    @ColumnInfo(name = "first_name")
    public String firstName;
}

במקרים שבהם טבלה תומכת בתוכן בכמה שפות, צריך להשתמש בפונקציה אפשרות languageId לציון העמודה ששמורה בה את פרטי השפה בכל שורה:

Kotlin

@Fts4(languageId = "lid")
@Entity(tableName = "users")
data class User(
    // ...
    @ColumnInfo(name = "lid") val languageId: Int
)

Java

@Fts4(languageId = "lid")
@Entity(tableName = "users")
public class User {
    // ...

    @ColumnInfo(name = "lid")
    int languageId;
}

בחדר יש כמה אפשרויות נוספות להגדרת ישויות שמתבססות על FTS, כולל סידור תוצאות, סוגי אסימונים וטבלאות שמנוהלות כתוכן חיצוני. עבור לקבלת פרטים נוספים על האפשרויות האלה, FtsOptions.

עמודות ספציפיות לאינדקס

אם האפליקציה שלך חייבת לתמוך בגרסאות SDK שלא תומכות ב-FTS3 ישויות עם גיבוי טבלה של FTS4, עדיין אפשר להוסיף לאינדקס עמודות מסוימות במסד הנתונים כדי לזרז את ביצוע השאילתות. כדי להוסיף אינדקסים לישות, צריך לכלול את הפרמטר indices בנכס בתוך @Entity הערה, לפרט את שמות העמודות שברצונך לכלול באינדקס או אינדקס מורכב. קטע הקוד הבא מדגים את ההערה תהליך:

Kotlin

@Entity(indices = [Index(value = ["last_name", "address"])])
data class User(
    @PrimaryKey val id: Int,
    val firstName: String?,
    val address: String?,
    @ColumnInfo(name = "last_name") val lastName: String?,
    @Ignore val picture: Bitmap?
)

Java

@Entity(indices = {@Index("name"),
        @Index(value = {"last_name", "address"})})
public class User {
    @PrimaryKey
    public int id;

    public String firstName;
    public String address;

    @ColumnInfo(name = "last_name")
    public String lastName;

    @Ignore
    Bitmap picture;
}

לפעמים שדות מסוימים או קבוצות של שדות במסד הנתונים חייבים להיות ייחודיים. אפשר לאכוף את מאפיין הייחודיות הזה על ידי הגדרה של unique נכס של @Index הערה ל-true. דוגמת הקוד הבאה מונעת מטבלה לקבל שתי שורות שמכילות את אותה קבוצת ערכים עבור הפונקציה firstName lastName עמודות:

Kotlin

@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?,
    @Ignore var picture: Bitmap?
)

Java

@Entity(indices = {@Index(value = {"first_name", "last_name"},
        unique = true)})
public class User {
    @PrimaryKey
    public int id;

    @ColumnInfo(name = "first_name")
    public String firstName;

    @ColumnInfo(name = "last_name")
    public String lastName;

    @Ignore
    Bitmap picture;
}

הכללת אובייקטים המבוססים על AutoValue

בחדר 2.1.0 ואילך אפשר להשתמש בערך לא ניתן לשינוי שמבוסס על Java class, שאתה מוסיף לו הערות באמצעות @AutoValue, כישויות במסד הנתונים של האפליקציה. הזה היא שימושית במיוחד כאשר מביאים בחשבון שני מופעים של ישות להיות שווה אם העמודות שלהן מכילות ערכים זהים.

כשמשתמשים בכיתות עם הערות @AutoValue כישויות, אפשר להוסיף הערות השיטות המופשטות של הכיתה באמצעות @PrimaryKey, @ColumnInfo, @Embedded ו- @Relation עם זאת, כשמשתמשים בהערות אלה, צריך לכלול את הערה אחת (@CopyAnnotations) בכל פעם, כדי שחדר יוכל לפרש את השיטות שנוצרו באופן אוטומטי כמו שצריך.

בקטע הקוד הבא מוצגת דוגמה לכיתה שמסומנת בהערה עם @AutoValue שהחדר מזהה כישות:

User.Java

@AutoValue
@Entity
public abstract class User {
    // Supported annotations must include `@CopyAnnotations`.
    @CopyAnnotations
    @PrimaryKey
    public abstract long getId();

    public abstract String getFirstName();
    public abstract String getLastName();

    // Room uses this factory method to create User objects.
    public static User create(long id, String firstName, String lastName) {
        return new AutoValue_User(id, firstName, lastName);
    }
}