گاهی اوقات، ممکن است بخواهید برنامه شما با پایگاه داده ای شروع شود که قبلاً با مجموعه خاصی از داده ها بارگذاری شده است. به این می گویند از پیش پر کردن پایگاه داده. در Room 2.2.0 و بالاتر، میتوانید از روشهای API برای پر کردن پایگاه داده اتاق در زمان اولیه با محتویات یک فایل پایگاه داده از پیش بستهبندی شده در سیستم فایل دستگاه استفاده کنید.
برای پر کردن یک پایگاه داده اتاق از فایل پایگاه داده از پیش بسته بندی شده که در هر جایی از فهرست assets/
برنامه شما قرار دارد، قبل از فراخوانی build()
متد createFromAsset()
از شی RoomDatabase.Builder
فراخوانی کنید:
Room.databaseBuilder(appContext, AppDatabase::class.java, "Sample.db") .createFromAsset("database/myapp.db") .build()
Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db") .createFromAsset("database/myapp.db") .build();
متد createFromAsset()
یک آرگومان رشته ای را می پذیرد که شامل یک مسیر نسبی از فهرست assets/
به فایل پایگاه داده از پیش بسته بندی شده است.
برای پر کردن یک پایگاه داده اتاق از یک فایل پایگاه داده از پیش بسته بندی شده که در هر جایی از سیستم فایل دستگاه به جز فهرست assets/
برنامه شما قرار دارد، قبل از فراخوانی build()
متد createFromFile()
را از شی RoomDatabase.Builder
خود فراخوانی کنید:
Room.databaseBuilder(appContext, AppDatabase::class.java, "Sample.db") .createFromFile(File("mypath")) .build()
Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db") .createFromFile(new File("mypath")) .build();
متد createFromFile()
آرگومان File
برای فایل پایگاه داده از پیش بسته بندی شده می پذیرد. Room به جای باز کردن مستقیم فایل تعیین شده، یک کپی از فایل تعیین شده ایجاد می کند، بنابراین مطمئن شوید که برنامه شما مجوزهای خواندن فایل را دارد.
فایل های پایگاه داده از پیش بسته بندی شده همچنین می توانند روشی را که پایگاه داده اتاق شما با مهاجرت های برگشتی مدیریت می کند تغییر دهد. به طور معمول، زمانی که مهاجرت های مخرب فعال هستند و اتاق باید بدون مسیر مهاجرت، مهاجرت را انجام دهد، اتاق تمام جداول در پایگاه داده را حذف می کند و یک پایگاه داده خالی با طرحواره مشخص شده برای نسخه هدف ایجاد می کند. با این حال، اگر یک فایل پایگاه داده از پیش بسته بندی شده را با همان شماره نسخه مورد نظر وارد کنید، Room سعی می کند پس از انجام مهاجرت مخرب، پایگاه داده تازه ایجاد شده را با محتویات فایل پایگاه داده از پیش بسته بندی شده پر کند.
برای اطلاعات بیشتر در مورد انتقال پایگاه داده اتاق، به پایگاه داده مهاجرت اتاق مراجعه کنید.
در بخشهای بعدی چند نمونه از نحوه عملکرد این روش در عمل ارائه میشود.
موارد زیر را فرض کنید:
- برنامه شما یک پایگاه داده اتاق را در نسخه 3 تعریف می کند.
- نمونه پایگاه داده ای که قبلاً روی دستگاه نصب شده است در نسخه 2 است.
- یک فایل پایگاه داده از پیش بسته بندی شده وجود دارد که در نسخه 3 است.
- هیچ مسیر انتقالی از نسخه 2 به نسخه 3 وجود ندارد.
- مهاجرت های مخرب فعال هستند.
// 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()
// 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();
در اینجا اتفاقی که در این شرایط رخ می دهد:
- از آنجا که پایگاه داده تعریف شده در برنامه شما در نسخه 3 است و نمونه پایگاه داده که قبلاً روی دستگاه نصب شده است در نسخه 2 است، انتقال ضروری است.
- از آنجایی که هیچ برنامه مهاجرتی از نسخه 2 به نسخه 3 اجرا نشده است، مهاجرت یک انتقال مجدد است.
- از آنجایی که متد سازنده
fallbackToDestructiveMigration()
فراخوانی می شود، مهاجرت بازگشتی مخرب است. Room نمونه پایگاه داده نصب شده روی دستگاه را حذف می کند. - از آنجایی که یک فایل پایگاه داده از پیش بسته بندی شده در نسخه 3 وجود دارد، Room پایگاه داده را دوباره ایجاد می کند و با استفاده از محتویات فایل پایگاه داده از پیش بسته بندی شده، آن را پر می کند. از طرف دیگر، اگر فایل پایگاه داده از پیش بسته بندی شده روی نسخه 2 باشد، اتاق توجه می کند که با نسخه هدف مطابقت ندارد و از آن به عنوان بخشی از مهاجرت بازگشتی استفاده نمی کند.
در عوض فرض کنید برنامه شما یک مسیر مهاجرت از نسخه 2 به نسخه 3 را پیاده سازی می کند:
// 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()
// 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();
در اینجا اتفاقی که در این شرایط رخ می دهد:
- از آنجایی که پایگاه داده تعریف شده در برنامه شما در نسخه 3 است و پایگاه داده از قبل نصب شده روی دستگاه در نسخه 2 است، انتقال ضروری است.
- از آنجایی که یک مسیر انتقال از نسخه 2 به نسخه 3 وجود دارد، Room متد
migrate()
تعریف شده را اجرا می کند تا نمونه پایگاه داده روی دستگاه را به نسخه 3 به روز کند و داده هایی را که از قبل در پایگاه داده است حفظ کند. Room از فایل پایگاه داده از پیش بسته بندی شده استفاده نمی کند، زیرا Room از فایل های پایگاه داده از پیش بسته بندی شده فقط در صورت انتقال مجدد استفاده می کند.
فایلهای پایگاه داده از پیش بستهبندی شده نیز میتوانند بر مهاجرتهایی که از چند مرحله تشکیل شدهاند تأثیر بگذارند. مورد زیر را در نظر بگیرید:
- برنامه شما یک پایگاه داده اتاق را در نسخه 4 تعریف می کند.
- نمونه پایگاه داده ای که قبلاً روی دستگاه نصب شده است در نسخه 2 است.
- یک فایل پایگاه داده از پیش بسته بندی شده وجود دارد که در نسخه 3 است.
- یک مسیر انتقال از نسخه 3 به نسخه 4 وجود دارد، اما از نسخه 2 به نسخه 3 وجود ندارد.
- مهاجرت های مخرب فعال هستند.
// 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()
// 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();
در اینجا اتفاقی که در این شرایط رخ می دهد:
- از آنجا که پایگاه داده تعریف شده در برنامه شما در نسخه 4 است و نمونه پایگاه داده قبلاً روی دستگاه نصب شده در نسخه 2 است، انتقال ضروری است.
- از آنجایی که هیچ مسیر مهاجرتی از نسخه 2 به نسخه 3 وجود ندارد، مهاجرت یک انتقال بازگشتی است.
- از آنجایی که متد سازنده
fallbackToDestructiveMigration()
فراخوانی می شود، مهاجرت بازگشتی مخرب است. Room نمونه پایگاه داده را روی دستگاه حذف می کند. - از آنجایی که یک فایل پایگاه داده از پیش بسته بندی شده در نسخه 3 وجود دارد، Room پایگاه داده را دوباره ایجاد می کند و با استفاده از محتویات فایل پایگاه داده از پیش بسته بندی شده، آن را پر می کند.
- پایگاه داده نصب شده بر روی دستگاه اکنون در نسخه 3 است. از آنجایی که این هنوز از نسخه تعریف شده در برنامه شما کمتر است، انتقال دیگری ضروری است.
- از آنجایی که یک مسیر انتقال از نسخه 3 به نسخه 4 وجود دارد، Room متد
migrate()
تعریف شده را اجرا می کند تا نمونه پایگاه داده روی دستگاه را به نسخه 4 به روز کند، و داده هایی را که از فایل پایگاه داده از پیش بسته بندی شده نسخه 3 کپی شده است، حفظ می کند.
برای کسب اطلاعات بیشتر در مورد از قبل پر کردن پایگاه داده اتاق، به منابع اضافی زیر مراجعه کنید.
- چیزهای جدید در اتاق (Android Dev Summit '19)