بگذارید با متدوالترین سوال ممکن درباره Room شروع کنیم، چرا من برای مدیریت دیتابیس Sqlite خودم از Room استفاده کنم در حالی که به خوبی دارم از Sqlite استفاده میکنم. جواب به این سوال در مشکلات زیر است.
مشکلات عمده در استفاده از Sqlite
۱) در زمان کامپایل هیچ بررسی بر روی کوئریها انجام نمیشود. برای مثال اگر شما در یک کوئری اسم یک ستون را به اشتباه نوشته باشید که اصلا وجود خارجی در دیتابیس نداشته باشد در نهایت شما یک خطا در زمان اجرا خواهید گرفت و هیچ خطایی در زمان کامپایل مشاهده نخواهید کرد.
۲) اگر شما schema دیتابیس خودتان را تغییر دهید نیاز دارید تا تمامی query های دیتابیس که نیاز به تغییر دارند را به صورت دستی تغییر دهید که این فرایند وقتگیر است و خود مستعد ایجاد خطاست.
۳) شما برای تبدیل کوئری به یک شیء جاوا باید تعداد زیادی کد تکراری بنویسید.
کاری که Room برای ما انجام داده این است که یک لایه مجزا و بالاتر از Sqlite ایجاد کرده است که ما به وسیلهی آن میتوانیم بر Sqlite مسلط شویم و از تمامی قدرت آن استفاده کنیم.
اکنون برویم سراغ نحوهی نصب و استفاده از Room persistence
نحوه نصب Room persistence
برای اضافه کردن Room ابتدا به فایل build.gradle پروژه خود بروید و سپس maven repo گوگل را به مانند کد زیر اضافه کنید:
allprojects { repositories { jcenter() maven { url 'https://maven.google.com' } } }
حال فایل build.gradle برنامه خود را باز کنید و در آن dependency های زیر را وارد کنید
implementation "android.arch.persistence.room:runtime:1.0.0-beta2" annotationProcessor "android.arch.persistence.room:compiler:1.0.0-beta2"
برای تست کردن انتقال دیتابیس از Sqlite به Room به dependency زیر نیز نیاز پیدا خواهید کرد
testImplementation "android.arch.persistence.room:testing:1.0.0-beta2"
کتابخانهی Room از RxJava نیز پشتیبانی میکند که برای استفاده از آن نیز باید dependency زیر را اضافه کنید
implementation "android.arch.persistence.room:rxjava2:1.0.0-beta2"
نحوه استفاده از دیتابیس Room
شمای کلی عملکرد به صورت زیر است:
سه بخش عمده در Room وجود دارد:
۱) مولفه Database
این مولفه نشان دهنده نمای کلی دیتابیس است، کلاس حاشیه نویسی شده به Database حتما باید فرزند RoomDatabase باشد و از نوع abstract تعریف شده باشد
و در طول اجرای برنامه شما میتونید با استفاده از Room.databaseBuilder() و یا Room.inMemoryDatabaseBuilder() به یک شی از این کلاس دسترسی داشته باشید
مثال:
@Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
۲) مولفه DAO
مهمترین بخش در Room همین DAO است که تمامی متدهای ارتباط با دیتابیس در داخل این کلاس تعریف میشوند
مثال:
@Dao public interface UserDao { @Query("SELECT * FROM user") List<User> getAll(); @Query("SELECT * FROM user WHERE uid IN (:userIds)") List<User> loadAllByIds(int[] userIds); @Query("SELECT * FROM user WHERE first_name LIKE :first AND " + "last_name LIKE :last LIMIT 1") User findByName(String first, String last); @Insert void insertAll(User... users); @Delete void delete(User user); }
۳) مولفه Entity
در این کلاس فیلدهای مربوط به دیتابیس تعریف میشوند و تمامی فیلدهای موجود در آن بر روی دیتابیس اعمال میشوند بجز آنهایی که با @ignore حاشیه نویسی شده باشند
مثال:
@Entity class User { @PrimaryKey public int id; public String firstName; public String lastName; @Ignore Bitmap picture; }
حال ما با موفقیت Database , DAO , Entity را ساختیم اکنون وقت آن رسیده که از آنها استفاده کنیم در کد زیر یک مثال از چگونگی استفاده از Room و تعامل با Sqlite آورده ایم برای استفاده از Room و انجام هرگونه عملیاتی چون وارد کردن اطلاعات در دیتابیس باید دقت داشته باشید که thread شما از نوع worker باشد.
// Get an Instance of Database class AppDatabase mDb = Room.inMemoryDatabaseBuilder(context, AppDatabase.class).build(); // Get DAO object UserDao mUserDao = mDb.getUserDao(); // Create User object to insert User user = TestUtil.createUser(3); user.setName("george"); // insert it in database mUserDao.insert(user);
تجربه استفاده از دیتابیس Room
استفاده کردن از Room معمولا ساده تر از استفادهی مستقیم از Sqllite است
در زمان کامپایل کدهای دیتابیسی چک میشوند و از خطاهای احتمالی در زمان کامپایل با خبر میشویم.
اگر شما از Database , DAO, Entity استفاده کنید کد شما ماژولار تر شده و خوانایی کد تا حد قابل قبولی بیشتر میشود.