JetPack组件开发5-----Room(另一种方式访问SQLite数据库)2

在上一节中,简单介绍了Room的基本用法,那么从本节开始,就再介绍Room的其他使用方法。

1、LiveData

在上一节中,通过查询数据库的全部内容,加载到界面上。那么在此Room可以支持LiveData,而且能够感知数据库数据的变化,当数据的数据发生变化时,会实时动态地更新数据到数据库。

 @Query("SELECT * FROM STUDENT")
//    List getAllStudent();
    LiveData<List<Student>> getAllLives();
 allLives = studentDao.getAllLives();
        allLives.observe(this, new Observer<List<Student>>() {
            @Override
            public void onChanged(List<Student> students) {
                adapter = new ListViewAdapter(getApplicationContext(),students);
                lv_main.setAdapter(adapter);
            }
        });

当执行添加、删除操作时,LiveData会感知数据库的数据变化,从而动态地显示数据。

2、AsyncTask

AsyncTask是Android中一种异步任务框架,是一个泛型抽象类,常见的就是3参数、5方法,有在后台子线程执行异步任务的doInBackground,也有在主线程更新UI的onPostExecute方法…

在上一节中,使用Room时是在主线程做的操作,是因为加了allowMainThreadQueries()允许在主线程执行查询操作,但是数据库的操作一般是不允许在主线程的,因此就需要用到AsyncTask

static class InsertTask extends AsyncTask<Student,Void,Void>{
        private StudentDao dao;

         public InsertTask(StudentDao dao) {
             this.dao = dao;
         }

         @Override
         protected Void doInBackground(Student... students) {
             dao.insertStudent(students);
             return null;
         }
     }

通过这样的方式在后台进行DML操作,就可以不写allowMainThreadQueries()这段代码了。

//插入数据
        btn_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Student student = new Student("小王",13);
                new InsertTask(studentDao).execute(student);
            }
        });

3、ViewModel

这样改进之后,Activity端的代码显得非常臃肿,因此可以使用ViewModel,作为中间载体,来作为View层界面请求数据源。

ViewModel之前在MVVM架构中,已经介绍很多了,包括它的生命周期等。

public class StudentViewModel extends AndroidViewModel {
    private StudentDataBase dataBase;
    private StudentDao dao;
    //数据源
    private LiveData<List<Student>> getAll;
    public StudentViewModel(@NonNull Application application) {
        super(application);
        dataBase = StudentDataBase.getInstance(application);
        dao = dataBase.getDao();
    }

    //请求插入数据
    public void insert(Student... students){
        new InsertTask(dao).execute(students);
    }

    //查询数据
    public AsyncTask<String, Void, Integer> getAgeByName(String name){
        return  new QueryTask(dao).execute(name);
    }


    public LiveData<List<Student>> getLive(){
        if(getAll == null){
            getAll = dao.getAllLives();
        }
        return getAll;
    }

    static class InsertTask extends AsyncTask<Student,Void,Void> {
        private StudentDao dao;

        public InsertTask(StudentDao dao) {
            this.dao = dao;
        }

        @Override
        protected Void doInBackground(Student... students) {
            dao.insertStudent(students);
            return null;
        }
    }

    static class QueryTask extends AsyncTask<String, Void, Integer> {
        private StudentDao dao;

        public QueryTask(StudentDao dao) {
            this.dao = dao;
        }

        @Override
        protected Integer doInBackground(String... strings) {
            int age = dao.getStudentByName(strings[0]);
            return age;
        }
    }

}

在View层界面,就可以实例化ViewModel使用内部的方法。

viewModel = new ViewModelProvider(this,
                new ViewModelProvider.AndroidViewModelFactory(getApplication()))
                .get(StudentViewModel.class);
        allLives = viewModel.getLive();
        allLives.observe(this, new Observer<List<Student>>() {
            @Override
            public void onChanged(List<Student> students) {
                adapter = new ListViewAdapter(getApplicationContext(),students);
                lv_main.setAdapter(adapter);
            }
        });

4、Model层实例Repository

在MVVM架构中,也包括在MVP架构中,有讲过Model的主要职责,除了网络请求之外,还有数据库的查询数据也是在Model层执行。

所以还要抽出一个Model层,在Room中,使用一个仓库类Repository。

public class StudentRepository {
    //数据请求
    private StudentDataBase dataBase;
    private StudentDao dao;

    private LiveData<List<Student>> getAll;

    public StudentRepository(Context context) {
        dataBase = StudentDataBase.getInstance(context.getApplicationContext());;
        dao = dataBase.getDao();
    }

    public LiveData<List<Student>> getGetAll() {
        if(getAll == null) {
            getAll = dao.getAllLives();
        }
        return getAll;
    }

    //插入数据
    //请求插入数据
    public void insert(Student... students){
        new InsertTask(dao).execute(students);
    }

    static class InsertTask extends AsyncTask<Student,Void,Void> {
        private StudentDao dao;

        public InsertTask(StudentDao dao) {
            this.dao = dao;
        }

        @Override
        protected Void doInBackground(Student... students) {
            dao.insertStudent(students);
            return null;
        }
    }

}

再对比一下之前的ViewModel,是不更简洁了一些。

public class StudentViewModel extends AndroidViewModel {
    private StudentRepository repository;
    //数据源
    private LiveData<List<Student>> getAll;
    public StudentViewModel(@NonNull Application application) {
        super(application);
        repository = new StudentRepository(application);
    }
    //请求插入数据
    public void insert(Student... students){
        repository.insert(students);
    }
    public LiveData<List<Student>> getLive(){
       getAll = repository.getGetAll();
       return getAll;
    }
}

你可能感兴趣的:(JetPack组件开发5-----Room(另一种方式访问SQLite数据库)2)