אכלוס מראש את מסד הנתונים Room

לפעמים תרצה שהאפליקציה שלך תתחיל עם מסד נתונים שכבר נטען עם מערך נתונים ספציפי. התהליך הזה נקרא אכלוס מראש של מסד נתונים. בחדר 2.2.0 ואילך, אתם יכולים להשתמש ב-methods של API כדי לאכלס מראש מסד נתונים של 'חדר' באתחול עם תוכן מקובץ מסד נתונים ארוז מראש במערכת הקבצים.

אכלוס מראש מנכס אפליקציה

כדי לאכלס מראש מסד נתונים מסוג Room מקובץ מסד נתונים ארוז מראש שנמצא במקום כלשהו בספריית assets/ של האפליקציה, קוראים אל createFromAsset() מאובייקט RoomDatabase.Builder לפני הקריאה ל-build():

Kotlin

Room.databaseBuilder(appContext, AppDatabase::class.java, "Sample.db")
    .createFromAsset("database/myapp.db")
    .build()

Java

Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
    .createFromAsset("database/myapp.db")
    .build();

ה-method createFromAsset() מקבלת ארגומנט מחרוזת שמכיל הנתיב היחסי מהספרייה assets/ לקובץ מסד הנתונים הארוז מראש.

אכלוס מראש ממערכת הקבצים

כדי לאכלס מראש מסד נתונים מסוג Room מקובץ מסד נתונים ארוז מראש שנמצא בכל מקום במערכת הקבצים של המכשיר חוץ מספריית assets/ של האפליקציה, קוראים ל-method createFromFile() מהאובייקט RoomDatabase.Builder לפני שמתקשרים ל-build():

Kotlin

Room.databaseBuilder(appContext, AppDatabase::class.java, "Sample.db")
    .createFromFile(File("mypath"))
    .build()

Java

Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
    .createFromFile(new File("mypath"))
    .build();

ה-method createFromFile() מקבלת ארגומנט File עבור של מסד נתונים ארוז מראש. במקום זאת, החדר יוצר עותק של הקובץ הייעודי. מאשר לפתוח אותו ישירות, לכן חשוב לוודא שלאפליקציה יש הרשאות קריאה חדש.

טיפול בהעברות שכוללות מסדי נתונים ארוזים מראש

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

מידע נוסף על העברות של מסדי נתונים מחדרים זמין במאמר מיגרציה של חדרים מסדי נתונים.

בקטעים הבאים מוצגות כמה דוגמאות לאופן שבו הכלים האלה עובדים בפועל.

דוגמה: העברה חלופית עם מסד נתונים ארוז מראש

נניח ש:

  • באפליקציה שלך מוגדר מסד נתונים מסוג 'חדר' בגרסה 3.
  • מופע מסד הנתונים שכבר מותקן במכשיר נמצא בגרסה 2.
  • יש קובץ מסד נתונים ארוז מראש בגרסה 3.
  • אין נתיב העברה מוטמע מגרסה 2 לגרסה 3.
  • העברות הרסניות מופעלות.

Kotlin

// Database class definition declaring version 3.
@Database(version = 3)
abstract class AppDatabase : RoomDatabase() {
    ...
}

// Destructive migrations are enabled and a prepackaged database
// is provided.
Room.databaseBuilder(appContext, AppDatabase::class.java, "Sample.db")
    .createFromAsset("database/myapp.db")
    .fallbackToDestructiveMigration()
    .build()

Java

// Database class definition declaring version 3.
@Database(version = 3)
public abstract class AppDatabase extends RoomDatabase {
    ...
}

// Destructive migrations are enabled and a prepackaged database
// is provided.
Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
    .createFromAsset("database/myapp.db")
    .fallbackToDestructiveMigration()
    .build();

זה מה שקורה במצב כזה:

  1. כי מסד הנתונים שמוגדר באפליקציה שלך הוא בגרסה 3 ומסד הנתונים שהמכונה שכבר מותקנת במכשיר נמצאת בגרסה 2, מתבצעת העברה הנחוצים.
  2. מכיוון שאין תוכנית העברה שהוטמעה מגרסה 2 לגרסה 3, ההעברה היא סוג של מיגרציה חלופית.
  3. כי שיטת ה-builder fallbackToDestructiveMigration() שנקראת 'ההעברה החלופית', היא הרסנית. מסד הנתונים של החדר לא תקין שמותקן במכשיר.
  4. מכיוון שיש קובץ מסד נתונים ארוז מראש בגרסה 3, Room יוצרת מחדש את מסד הנתונים ומאכלסת אותו באמצעות התוכן של הנתונים הארוזים מראש קובץ מסד הנתונים. מצד שני, אם קובץ מסד הנתונים הארוז מראש היה בשלב 2, 'חדר' יציין שהוא לא תואם לגרסת היעד לא תשתמש בה כחלק מההעברה החלופית.

דוגמה: הטמעה של העברה עם מסד נתונים ארוז מראש

במקום זאת, נניח שבאפליקציה מוטמעת נתיב העברה מגרסה 2 אל גרסה 3:

Kotlin

// Database class definition declaring version 3.
@Database(version = 3)
abstract class AppDatabase : RoomDatabase() {
    ...
}

// Migration path definition from version 2 to version 3.
val MIGRATION_2_3 = object : Migration(2, 3) {
    override fun migrate(database: SupportSQLiteDatabase) {
        ...
    }
}

// A prepackaged database is provided.
Room.databaseBuilder(appContext, AppDatabase::class.java, "Sample.db")
    .createFromAsset("database/myapp.db")
    .addMigrations(MIGRATION_2_3)
    .build()

Java

// Database class definition declaring version 3.
@Database(version = 3)
public abstract class AppDatabase extends RoomDatabase {
    ...
}

// Migration path definition from version 2 to version 3.
static final Migration MIGRATION_2_3 = new Migration(2, 3) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        ...
    }
};

// A prepackaged database is provided.
Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
    .createFromAsset("database/myapp.db")
    .addMigrations(MIGRATION_2_3)
    .build();

זה מה שקורה במצב כזה:

  1. כי מסד הנתונים שמוגדר באפליקציה שלך הוא בגרסה 3 ומסד הנתונים שכבר מותקנת במכשיר בגרסה 2, נדרשת העברה.
  2. יש נתיב העברה שהוטמע מגרסה 2 לגרסה 3, החדר מפעיל את השיטה migrate() שהוגדרה כדי לעדכן את מסד הנתונים במכשיר לגרסה 3, תוך שימור הנתונים שכבר נמצאים במסד הנתונים. החדר לא משתמש בקובץ מסד הנתונים הארוז מראש, כי Room משתמשת בקובצי מסד נתונים ארוזים מראש רק במקרה של העברה חלופית.

דוגמה: העברה מרובת שלבים עם מסד נתונים ארוז מראש

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

  • באפליקציה שלך מוגדר מסד נתונים מסוג 'חדר' בגרסה 4.
  • מופע מסד הנתונים שכבר מותקן במכשיר נמצא בגרסה 2.
  • יש קובץ מסד נתונים ארוז מראש בגרסה 3.
  • קיים נתיב העברה שהוטמע מגרסה 3 לגרסה 4, אבל לא מגרסה 2 לגרסה 3.
  • העברות הרסניות מופעלות.

Kotlin

// Database class definition declaring version 4.
@Database(version = 4)
abstract class AppDatabase : RoomDatabase() {
    ...
}

// Migration path definition from version 3 to version 4.
val MIGRATION_3_4 = object : Migration(3, 4) {
    override fun migrate(database: SupportSQLiteDatabase) {
        ...
    }
}

// Destructive migrations are enabled and a prepackaged database is
// provided.
Room.databaseBuilder(appContext, AppDatabase::class.java, "Sample.db")
    .createFromAsset("database/myapp.db")
    .addMigrations(MIGRATION_3_4)
    .fallbackToDestructiveMigration()
    .build()

Java

// Database class definition declaring version 4.
@Database(version = 4)
public abstract class AppDatabase extends RoomDatabase {
    ...
}

// Migration path definition from version 3 to version 4.
static final Migration MIGRATION_3_4 = new Migration(3, 4) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        ...
    }
};

// Destructive migrations are enabled and a prepackaged database is
// provided.
Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
    .createFromAsset("database/myapp.db")
    .addMigrations(MIGRATION_3_4)
    .fallbackToDestructiveMigration()
    .build();

זה מה שקורה במצב כזה:

  1. כי מסד הנתונים שמוגדר באפליקציה שלך הוא בגרסה 4 ומסד הנתונים שהמכונה שכבר מותקנת במכשיר נמצאת בגרסה 2, מתבצעת העברה הנחוצים.
  2. מכיוון שאין נתיב העברה מוטמע מגרסה 2 לגרסה 3, ההעברה היא סוג של מיגרציה חלופית.
  3. כי שיטת ה-builder fallbackToDestructiveMigration() שנקראת 'ההעברה החלופית', היא הרסנית. מסד הנתונים של החדר לא תקין במופע של המכשיר.
  4. מכיוון שיש קובץ מסד נתונים ארוז מראש בגרסה 3, Room יוצרת מחדש את מסד הנתונים ומאכלסת אותו באמצעות התוכן של הנתונים הארוזים מראש קובץ מסד הנתונים.
  5. מסד הנתונים שמותקן במכשיר נמצא עכשיו בגרסה 3. כי זה עדיין נמוכה מהגרסה שהוגדרה באפליקציה, העברה אחרת הנחוצים.
  6. יש נתיב העברה שהוטמע מגרסה 3 לגרסה 4, החדר מפעיל את השיטה migrate() שהוגדרה כדי לעדכן את מסד הנתונים במכשיר לגרסה 4, תוך שימור הנתונים שהועתקו מקובץ מסד הנתונים הארוז מראש בגרסה 3.

מקורות מידע נוספים

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

סרטונים

בלוגים