بخش اول این مقاله رو میتونین اینجا بخونین
بیاین کلاس User
رو تغییر بدیم و یه ستون دیگه به جدول user
اضافه کنیم به اسم : last_update
. در کلاس UsersDatabase
نیاز داریم تا کارهای زیر رو انجام بدیم :
@Database(entities = {User.class}, version = 3) public abstract class UsersDatabase extends RoomDatabase
2. یک مهاجرت برای انتقال ورژن 2 به 3 اضافه کنیم :
static final Migration MIGRATION_2_3 = new Migration(2, 3) { @Override public void migrate(SupportSQLiteDatabase database) { database.execSQL("ALTER TABLE users " + " ADD COLUMN last_update INTEGER"); } };
3. مهاجرت رو به بیلدر دیتابیس روم اضافه کنیم :
database = Room.databaseBuilder(context.getApplicationContext(), UsersDatabase.class, "Sample.db") .addMigrations(MIGRATION_1_2, MIGRATION_2_3) .build();
وقتی اپ رو اجرا میکنیم مراحل زیر اتفاق می افتن:
قدم اول : تلاش برای اپگریت از ورژن 2 (ورژنی که روی دستگاه هست) به ورژن 3
room_master_table
✅قدم دوم : تلاش برای باز کردن دیتابیس
room_master_table
موجوده ٬ یکی هستن.✅دستور ALTER TABLE
در SQLite کاملا محدود است. برای مثال تغییر id کاربر از int
به String
نیازمند چند مرحله هست :
users
به جدول موقتusers
users
با Room ٬ پیاده سازی مهاجرت به شکل زیر هست :
static final Migration MIGRATION_3_4 = new Migration(3, 4) { @Override public void migrate(SupportSQLiteDatabase database) { // Create the new table database.execSQL( "CREATE TABLE users_new (userid TEXT, username TEXT, last_update INTEGER, PRIMARY KEY(userid))");// Copy the data database.execSQL( "INSERT INTO users_new (userid, username, last_update) SELECT userid, username, last_update FROM users");// Remove the old table database.execSQL("DROP TABLE users");// Change the table name to the correct one database.execSQL("ALTER TABLE users_new RENAME TO users"); } };
چه حالتی پیش میاد ٬
اگه کاربران شما یه نسخه قدیمی از اپ داشته باشن که در اون ورژن دیتابیس 1 باشه و شما بخواین ورژن اون رو به 4 افزایش بدین ؟
تا الان ما مهاجرت های زیر رو تعریف کردیم :
ورژن 1 به 2 ٬ ورژن 2 به 3 ٬ ورژن 3 به 4
پس Room همه مهاجرت ها رو یکی پس از دیگری اجرا میکنه.
اما خبر خوب اینه که Room میتونه افزایش چنتایی ورژن رو هندل کنه. ما میتونیم یه مهاجرت تعریف کنیم که در یک قدم از ورژن 1 مستقیم به 4 افزایش پیدا میکنه و طبیعتا روند کار سریع تر میشه.
static final Migration MIGRATION_1_4 = new Migration(1, 4) { @Override public void migrate(SupportSQLiteDatabase database) { // Create the new table database.execSQL( "CREATE TABLE users_new (userid TEXT, username TEXT, last_update INTEGER, PRIMARY KEY(userid))"); // Copy the data database.execSQL( "INSERT INTO users_new (userid, username, last_update) SELECT userid, username, last_update FROM users");// Remove the old table database.execSQL("DROP TABLE users");// Change the table name to the correct one database.execSQL("ALTER TABLE users_new RENAME TO users"); } };
در قدم بعدی فقط اون رو به لیست مهاجرت ها اضافه میکنیم :
database = Room.databaseBuilder(context.getApplicationContext(), UsersDatabase.class, "Sample.db") .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_1_4) .build();
حواستون باشه که برخلاف کوئریهای DAO ٬ کوئریهایی که توی پیاده سازی Migration.migrate
نوشتین ٬ در زمان اجرا کامپایل نمیشن. مطمئن بشین که که حتما برای مهاجرت هاتون تست نوشتین.
شما میتونین پیاده سازی رو اینجا ببینین. برای سهولت مقایسه هر ورژن دیتابیس در flavor خودش پیاده سازی شده :
1. پیاده سازی با sqlite _ با استفاده از SQLiteOpenHelper و اینترفیس های رایج sqlite
2. پیاده سازی با Room _ پیاده سازی را با Room جایگزین کرده و مهاجرت برای ورژن 2 فراهم میکنه.
3. پیاده سازی با Room 2 _ آپدیت دیتابیس به دیاگرام جدید ٬ ورژن 3
4. پیاده سازی با Room 3 _ آپدیت دیتابیس به ورژن 4. مسیر مهاجرت ها برای اپدیت از ورژن 2 به 3 ٬ ورژن 3 به 4 و ورژن 1 به 4 پیاده سازی شده .
دیاگرامتون عوض شده؟ فقط کافیه ورژن دیتابیس رو افزایش بدین و یه مهاجرت(Migration) رو پیاده سازی کنین. در نتیجه مطمئن میشین که اپ کرش نمیکنه و دیتا های کاربران از بین نمیره. به راحتی فشار دادن یه دکمه!
این مطلب ترجمه مقاله ای در مدیوم هست که اینجا میتونین بخونین.
همچنین میتونین مطلب های بیشتر رو در سایت من بخونین
در پایان اگه نظر یا پیشنهادی دارین خوشحال میشم در زیر این پست بخونم :)