آموزش دیتابیس Room در اندروید

آموزش دیتابیس Room در اندروید

پایگاه داده ی Room یکی از جدیدترین کتابخانه هایی است که توسط گوگل برای ساخت دیتابیس ارائه شده است .

اگر یک اندروید نویس حرفه ای باشید قطعا میدانید که پایگاه داخلی اندروید با Sqlite ساخته میشود ، در واقع این کتابخانه هم با استفاده از SqliteDatabase ساخته شده است و پشت زمینه این کتابخانه همان Sqlite خودمان است . اما خب این کتابخانه با استفاده از Entity کار را برای یک برنامه نویس بسیار ساده تر میکند ، یعنی به عبارتی برنامه نویس دغدغه ی توسعه ی یک پایگاه داده را ندارد …

نکته :پیشنهاد میکنم به افرادی که برنامه نویسی سمت سیستم عامل اندروید رو به تازگی شروع کرده اند حداقل یک اپلیکیشن با استفاده از روش قدیمی پایگاه داده داخل اندروید توسعه بدهند تا فهم برنامه نویسی برایشان راحت تر باشد .



خب بریم سراغ آموزش

  • کتابخانه

برای شروع کتابخانه های زیر رو به فایل Gradle پروژه ی خودتون اضافه کنید .




    implementation 'androidx.room:room-runtime:2.1.0-alpha04'
    annotationProcessor 'androidx.room:room-compiler:2.1.0-alpha04'



  • طراحی Model

خب برای راه اندازی این کتابخانه نیاز به یک مدل دارید

دقت کنید، مدل همان جدول شما خواهد بود که به صورت زیر تعریف میکنیم




@Entity(tableName = "not_pad")
public class NoteModel extends BaseObservable implements Serializable {

    @PrimaryKey(autoGenerate = true)
    private int id;

    private String title;
    private String decription;
    private String img;


    public NoteModel() {

    }

    public NoteModel(String title, String decription, String img) {
        this.title = title;
        this.decription = decription;
        this.img = img;
    }

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }


    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;

    }


    public String getDecription() {
        return decription;
    }
    public void setDecription(String decription) {
        this.decription = decription;

    }



    public String getImg() {
        return img;
    }
    public void setImg(String img) {
        this.img = img;
    }




}



همانطور که در کدهای بالا مشاهده میکنید ، قبل از تعریف کلاسمان نام جدولمان را با استفاده از Entity@ مشخص کرده ایم ، یعنی به عبارتی جدول ما در دیتابیس با نام not_pad میباشد و با PrimaryKey@ هم کلید اصلی جدولمان را مشخص کرده ایم

  • طراحی Query

با استفاده interface هایی که از Dao داخل کتابخانه ی ما پیروی میکنند ، میتونیم کوئری ها رو به شکل زیر طراحی کنیم .



@Dao
public interface NoteDao {

    @Insert
    void insert(NoteModel note);

    @Update
    void update(NoteModel note);

    @Delete
    void delete(NoteModel note);

    @Query("DELETE FROM not_pad")
    void deleteAllNote();

    @Query("SELECT * FROM not_pad ORDER BY id DESC")
    List<NoteModel> getAllNotes();

}

فکر میکنم افرادی که به صورت سنتی پایگاه داده طراحی میکرده اند ، متوجه شدن که چقدر کار ما برای طراحی کوئری ها راحت تر شده ! اما نگران نباشید ، به جاهای بهتری هم خواهیم رسید !

نکته : برای اجرای کوئری های فوق باید AsynTask نوشته بشه که در ادامه آموزش به آنها خواهیم رسید

  • طراحی DataBase

خب تا اینجا فعلا نیمی از راه رو برای طراحی رفته ایم .

حالا باید بریم سراغ طراحی خود دیتابیسمون که به صورت زیر انجام میشود




@Database(entities = {NoteModel.class},version = 1)
public abstract class DataBase extends RoomDatabase {

    private static DataBase instance;

    public abstract NoteDao noteDao();

    public static synchronized DataBase getInstance(Context context) {
        if(instance == null){
            instance = Room.databaseBuilder(context, DataBase.class,"not_database")
                    .addCallback(roomCallback)
                    .fallbackToDestructiveMigration()
                    .allowMainThreadQueries()
                    .build();
        }
        return instance;
    }



    private static Callback roomCallback = new Callback() {
        @Override
        public void onCreate(@NonNull SupportSQLiteDatabase db) {
            new PopulateDbAsynTask(instance).execute();
            super.onCreate(db);
        }
    };





    private static Callback roomCallback2 = new Callback() {
        @Override
        public void onOpen(@NonNull SupportSQLiteDatabase db) {
            super.onOpen(db);
        }
    };







    private static class PopulateDbAsynTask extends AsyncTask<Void,Void,Void> {
        private NoteDao noteDao;

        public PopulateDbAsynTask(DataBase noteDataBase) {
            noteDao = noteDataBase.noteDao();
        }

        @Override
        protected Void doInBackground(Void... voids) {

                noteDao.insert(new NoteModel("RecyclerView","DataBinding","https://www.theindianwire.com/wp-content/uploads/2018/10/Developer-Support-for-Huawei-Mate-SE.png"));
                noteDao.insert(new NoteModel("BaseObservable","ViewModel","https://www.theindianwire.com/wp-content/uploads/2018/10/Developer-Support-for-Huawei-Mate-SE.png"));
                noteDao.insert(new NoteModel("Sqlite","RoomDataBase","https://www.theindianwire.com/wp-content/uploads/2018/10/Developer-Support-for-Huawei-Mate-SE.png"));
                noteDao.insert(new NoteModel("DialogBinding","BaseObservable","https://www.theindianwire.com/wp-content/uploads/2018/10/Developer-Support-for-Huawei-Mate-SE.png"));
                noteDao.insert(new NoteModel("Glide","Load Images","https://www.theindianwire.com/wp-content/uploads/2018/10/Developer-Support-for-Huawei-Mate-SE.png"));

            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
        }
    }


کدهای بالا Database داخلی رو با کدهای فوق میسازیم .

اگر دقت کنید کلاس NoteModel رو که به عنوان Entity تعریف کردیم به DataBase@ بالای پروژه میدهیم …

در مورد ورژن دیتابیس دقت داشته باشید که اگر خواستید مقادیری اضافه کنید باید حتما ورژن رو تغییر بدید !

نکته : کلاس PopulateDbAsynTask که به صورت AsynTask اجرا میشود به جدول ما مقادیر ثابت و یا Defult که میخواهیم در اجرای اپلیکیشن داخل دیتابیس باشد رو Insert میکند . که از کلاس Interface هایی که به صورت Dao ساختیم برای insert استفاده میکند .



  • طراحی Repository

اگر یادتان باشد در مطالب فوق گفتم برای اجرای کوئری ها نیاز به طراحی AsynTask دارید .

به همین دلیل از کلاسی با نام NoteRepository به شکل زیر میسازیم و از کوئری ها استفاده میکنیم .

به عبارت دیگر مهمترین کلاس دیتابیسمون کلاس زیر است … پس با دقت به کدهای زیر دقت کنید و یاد بگیرید 🙂





public class NoteRepository {
    private static NoteRepository instance;
    private NoteDao noteDao;
    private List<NoteModel> allnotes;


    public static NoteRepository getInstance(Context context) {
        if (instance == null)
            instance = new NoteRepository(context);
        return instance;
    }

    private NoteRepository(final Context context) {
        DataBase dataBase = DataBase.getInstance(context);
        noteDao = dataBase.noteDao();
        allnotes = noteDao.getAllNotes();

    }

    public void insert(final NoteModel note) {
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                noteDao.insert(note);
            }
        });
    }

    public void update(final NoteModel note) {
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                noteDao.update(note);
            }
        });
    }

    public void delete(final NoteModel note) {
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                noteDao.delete(note);
            }
        });
    }

    public void deleteAllnote() {
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                noteDao.deleteAllNote();
            }
        });

    }


    public List<NoteModel> getAllnotes() {
        try {
            return new GetNotesAsyncTask().execute().get();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }






    @SuppressLint("StaticFieldLeak")
    private class GetNotesAsyncTask extends AsyncTask<Void, Void, List<NoteModel>> {
        @Override
        protected List<NoteModel> doInBackground(Void... voids) {
            return noteDao.getAllNotes();
        }
    }





}



نکته : همانطور که مشاهده میکنید کلاسمان به صورت دیزاین پترن Singleton طراحی شده است تا فقط یکبار ساخته شود ! برای آموزش Singleton روی همین متن کلیک کنید ..

در کلاس فوق کلاس DataBase که ساختیم رو صدا میزنیم و به صورت AsynTask برای هر کدام از کوئری ها تابع تعریف میکنیم که به صورت زیر از کلاسهامون استفاده میکنیم .

  • اجرای دیتابیس

با کد زیر میتونیم کل اطلاعات دیتابیس رو خیلی راحت دریافت کنیم 🙂



NoteRepository.getInstance(context).getAllnotes()



امیدوارم از آموزش فوق لذت برده باشید .

با نظرتان ارزشمند خودتان ما رو بی نصیب نذارید



برای دانلود سورس کد کلیک کنید


دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *