這篇文章是對上篇文章的優化。增加兩個類,一個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; } } }
運行結果: