这篇文章是对上篇文章的优化。增加两个类,一个ViewModel管理界面数据,一个仓库类存放类。
1、Room本身支持LiveData,使用LiveData,我们就可以不用每次对页面进行刷新操作(自己写的页面刷新函数 )。我们可以用observe来观察它是否发生改变,如果改变则进行页面改变。
2、在Database改成Singleton,因为在database构造实例是非常消耗资源的,所有我们只让它构造一个实例,节省资源
3、改变线程。上一篇文章数据库的操作是在主线程,这是不对的,应该把它放到工作线程。我们可以用AsyncTask。要用AsyncTask对数据库进行操作,就需要定义多个类来继承AsyncTask这个抽象类。
实体类:
package com.example.roomtest;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity // 实体类
public class Word {
@PrimaryKey(autoGenerate = true) // 将id设置为主键,并且自增
private int id;
@ColumnInfo(name = "English") // 设置每列的名称
private String English_word;
@ColumnInfo(name = "Chinese")
private String Chinese_meaning;
// 主键不用构造函数
public Word(){}
public Word(String english_word, String chinese_meaning) {
English_word = english_word;
Chinese_meaning = chinese_meaning;
}
public void setId(int id){
this.id = id;
}
public int getId() {
return id;
}
public String getEnglish_word() {
return English_word;
}
public void setEnglish_word(String english_word) {
English_word = english_word;
}
public String getChinese_meaning() {
return Chinese_meaning;
}
public void setChinese_meaning(String chinese_meaning) {
Chinese_meaning = chinese_meaning;
}
}
Dao:
package com.example.roomtest;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
@Dao // 访问数据库操作的接口 Database access object
public interface WordDao {
//我们所有对数据库的操作都在Dao里声明
@Insert // 这些修饰词会在编译时候生成代码
void insertWords(Word... words); // 如果是一个参数就写 Word word,多个参数就这样写
@Update
void updataWords(Word... words);
@Delete
void deleteWords(Word... words);
@Query("DELETE FROM WORD")
void deleteAllWords();
@Query("SELECT * FROM WORD ORDER BY ID DESC") // 获取所有的WORD,并且按照id降序排序
LiveData<List<Word>> getAllWordsLive();
}
Database:
package com.example.roomtest;
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
// singleton
/*
这里有个参数,第一个参数entities是一个集合,因为只有一个实体类,如果有多个可以逗号隔开
第二个参数是version(版本):每一次数据库的结构发生改变,版本都得改变
第三个参数是生成数据库表:这里先选择false
*/
@Database(entities = {Word.class},version = 1,exportSchema = false)
public abstract class WordDatabase extends RoomDatabase {
private static WordDatabase INSTANCE;
// 因为需要一个Context,所有我们得传来一个Context
static synchronized WordDatabase getDatabase(Context context){
if(INSTANCE==null){
INSTANCE = Room.databaseBuilder(context.getApplicationContext(), WordDatabase.class, "word_database")
.allowMainThreadQueries().build();
}
return INSTANCE;
}
public abstract WordDao getWordDao();
}
ViewModel:
package com.example.roomtest;
import android.app.Application;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import java.util.List;
public class WordViewModel extends AndroidViewModel {
private WordRepository wordRepository;
public WordViewModel(@NonNull Application application) {
super(application);
wordRepository = new WordRepository(application);
}
public LiveData<List<Word>> getAllWordLive() {
return wordRepository.getAllWordLive();
}
// 定义类的接口-- 插入
public void insertWords(Word...words){
wordRepository.insertWords(words);
}
// 定义类的接口-- 删除
public void deleteWords(Word...words){
wordRepository.deleteWords(words);
}
// 定义类的接口-- 清空
public void deleteAllWords(){
wordRepository.deleteAllWords();
}
// 定义类的接口-- 修改
public void updataWords(Word...words){
wordRepository.updataWords(words);
}
}
Repository:
package com.example.roomtest;
import android.content.Context;
import android.os.AsyncTask;
import androidx.lifecycle.LiveData;
import java.util.List;
public class WordRepository {
private LiveData<List<Word>> allWordLive;
private WordDao wordDao;
public WordRepository(Context context) {
WordDatabase wordDatabase = WordDatabase.getDatabase(context.getApplicationContext());
wordDao = wordDatabase.getWordDao();
allWordLive = wordDao.getAllWordsLive();
}
public LiveData<List<Word>> getAllWordLive() {
return allWordLive;
}
// 定义类的接口-- 插入
public void insertWords(Word...words){
new InsertAsyncTask(wordDao).execute(words);
}
// 定义类的接口-- 删除
public void deleteWords(Word...words){
new DeleteAsyncTask(wordDao).execute(words);
}
// 定义类的接口-- 清空
public void deleteAllWords(){
new DeleteAllAsyncTask(wordDao).execute();
}
// 定义类的接口-- 修改
public void updataWords(Word...words){
new UpdataAsyncTask(wordDao).execute(words);
}
// 插入类
static class InsertAsyncTask extends AsyncTask<Word,Void,Void> {
private WordDao wordDao;
public InsertAsyncTask(WordDao wordDao) {
this.wordDao = wordDao;
}
// 将在主线程的工作放到后台来执行
@Override
protected Void doInBackground(Word... words) {
wordDao.insertWords(words);
return null;
}
}
// 删除类
static class DeleteAsyncTask extends AsyncTask<Word,Void,Void> {
private WordDao wordDao;
public DeleteAsyncTask(WordDao wordDao) {
this.wordDao = wordDao;
}
// 将在主线程的工作放到后台来执行
@Override
protected Void doInBackground(Word... words) {
wordDao.deleteWords(words);
return null;
}
}
// 清空类
static class DeleteAllAsyncTask extends AsyncTask<Void,Void,Void> {
private WordDao wordDao;
public DeleteAllAsyncTask(WordDao wordDao) {
this.wordDao = wordDao;
}
// 将在主线程的工作放到后台来执行
@Override
protected Void doInBackground(Void... voids) {
wordDao.deleteAllWords();
return null;
}
}
// 修改类
static class UpdataAsyncTask extends AsyncTask<Word,Void,Void> {
private WordDao wordDao;
public UpdataAsyncTask(WordDao wordDao) {
this.wordDao = wordDao;
}
// 将在主线程的工作放到后台来执行
@Override
protected Void doInBackground(Word... words) {
wordDao.updataWords(words);
return null;
}
}
}
运行结果:

