Room 让数据库变得无比高效简洁 2.一个简单的小例子的进阶和完善
介绍几个新东西
Async Task 把数据库的操作放到别的线程里,不能放在主线程
Repository 把数据库的内容放入View Model中,并引入LiveData
每次我们进行一步操作都得用我们自己写的UpdateView来刷新一下页面,LiveData就省去了我们这个烦恼
Room与LiveData+ViewModel结合使用
我们的MainActivity就应该专注于页面,自己写的类作为数据仓库,专注于对数据库的操作,ViewModel则是二者的桥梁。

依赖
def room_version = "2.2.0"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
implementation 'android.arch.lifecycle:extensions:1.1.1'
// optional - Test helpers
testImplementation "androidx.room:room-testing:$room_version"
先写一下实体类
package com.example.roomtwo.dao; import androidx.room.ColumnInfo; import androidx.room.Entity; import androidx.room.PrimaryKey; //@Entity(tableName = "haha") 如果不指定表名,则表名跟类名同,大小写敏感 @Entity public class Word { @PrimaryKey(autoGenerate = true) private int id; @ColumnInfo(name = "english_word") private String word; @ColumnInfo(name = "chinese_meaning") private String chineseMeaning; public Word(String word, String chineseMeaning) { this.word = word; this.chineseMeaning = chineseMeaning; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getWord() { return word; } public void setWord(String word) { this.word = word; } public String getChineseMeaning() { return chineseMeaning; } public void setChineseMeaning(String chineseMeaning) { this.chineseMeaning = chineseMeaning; } @Override public String toString() { return "Word{" + "id=" + id + ", word='" + word + '\'' + ", chineseMeaning='" + chineseMeaning + '\'' + '}'; } }
再写一下dao层接口
package com.example.roomtwo.dao; 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 public interface WordDao { @Insert void insertWords(Word...Word); @Update void updateWords(Word...Word); @Delete void deleteWords(Word...Word); @Query("delete from word") void deleteAllWords(); @Query("select * from Word") List<Word> getAllWords(); @Query("select * from Word") LiveData<List<Word>> getAllWordLiveData(); }
写一下创建数据库相关的类
package com.example.roomtwo.dao; import android.content.Context; import androidx.annotation.NonNull; import androidx.room.Dao; import androidx.room.Database; import androidx.room.DatabaseConfiguration; import androidx.room.InvalidationTracker; import androidx.room.Room; import androidx.room.RoomDatabase; import androidx.sqlite.db.SupportSQLiteOpenHelper; //singleton @Database(entities = Word.class,version = 1,exportSchema = false) public abstract class WordDatabase extends RoomDatabase { //单例模式创建以及获取数据库的实例 private static WordDatabase instance; public static synchronized WordDatabase getDatabase(Context context){ if (instance == null){ instance = Room.databaseBuilder(context.getApplicationContext(),WordDatabase.class,"fuck2.db") .allowMainThreadQueries() .build(); } return instance; } public abstract WordDao getWordDao(); }
专注于操作数据库的数据库仓库类
package com.example.roomtwo.dao; import android.content.Context; import android.os.AsyncTask; import androidx.lifecycle.LiveData; import java.util.List; public class WordRepository { private WordDao wordDao; private WordDatabase wordDatabase; private LiveData<List<Word>> allWordLive; public WordRepository(Context context) { //创建数据库 wordDatabase = WordDatabase.getDatabase(context.getApplicationContext()); //获取dao层接口 wordDao = wordDatabase.getWordDao(); //得到可观察的数据 allWordLive = wordDao.getAllWordLiveData(); } public LiveData<List<Word>> getAllWordLive() { return allWordLive; } /********************使用下面那几个增删改查的接口,方便别人调用**************************/ public void insertWords(Word...words){ new WordRepository.InsertAsyncTask(wordDao).execute(words); } public void updateWords(Word...words){ new WordRepository.UpdateAsyncTask(wordDao).execute(words); } public void deleteWords(Word...words){ new WordRepository.DeleteAsyncTask(wordDao).execute(words); } public void deleteAllWords(Void...voids){ new WordRepository.DeleteAllAsyncTask(wordDao).execute(); } //数据库不能运行在主线程中,我们现在有增删改查四个操作,就得在外面创建四个AsyncTask类文件 //为了方便,现在我们写成内部类 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 UpdateAsyncTask extends AsyncTask<Word,Void,Void>{ private WordDao wordDao; public UpdateAsyncTask(WordDao wordDao) { this.wordDao = wordDao; } //在后台上做操作 @Override protected Void doInBackground(Word... words) { wordDao.updateWords(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; } } //删除所有 没有参数就是Void 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; } } }
activity和数据的桥梁 ViewModel
package com.example.roomtwo; import android.app.Application; import android.os.AsyncTask; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProviders; import com.example.roomtwo.dao.Word; import com.example.roomtwo.dao.WordDao; import com.example.roomtwo.dao.WordDatabase; import com.example.roomtwo.dao.WordRepository; import java.util.List; public class WordViewModel extends AndroidViewModel { //数据仓库 private WordRepository wordRepository; //可观察的数据 private LiveData<List<Word>> allWordLive; public WordViewModel(@NonNull Application application) { super(application); wordRepository = new WordRepository(application); } public LiveData<List<Word>> getAllWordLive() { allWordLive = wordRepository.getAllWordLive(); return allWordLive; } /********************使用下面那几个增删改查的接口,方便别人调用**************************/ void insertWords(Word...words){ wordRepository.insertWords(words); } void updateWords(Word...words){ wordRepository.updateWords(words); } void deleteWords(Word...words){ wordRepository.deleteWords(words); } void deleteAllWords(Void...voids){ wordRepository.deleteAllWords(); } }
MainActivyty
package com.example.roomtwo; import androidx.appcompat.app.AppCompatActivity; import androidx.lifecycle.LiveData; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProviders; import androidx.room.Room; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import com.example.roomtwo.dao.Word; import com.example.roomtwo.dao.WordDao; import com.example.roomtwo.dao.WordDatabase; import java.util.List; public class MainActivity extends AppCompatActivity { WordDatabase wordDatabase; WordDao wordDao; WordViewModel wordViewModel; Button insertBtn; Button updateBtn; Button clearBtn; Button deleteBtn; TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //viewModel的实例化 wordViewModel = ViewModelProviders.of(this).get(WordViewModel.class); //可被观察的数据 wordViewModel.getAllWordLive().observe(this, new Observer<List<Word>>() { @Override public void onChanged(List<Word> words) { String text = null; for (int i = 0; i < words.size(); i++) { Word word = words.get(i); text += word.getId()+":"+word.getWord()+"="+word.getChineseMeaning(); } textView.setText(text); } }); //初始化各组件 initBtnAndView(); //插入 insertBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Word word = new Word("hello", "你好"); Word word1 = new Word("world", "世界"); wordViewModel.insertWords(word,word1); } }); //清空数据库表 clearBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { wordViewModel.deleteAllWords(); } }); //删除某一个字段 deleteBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Word word = new Word("", ""); word.setId(270); wordViewModel.deleteWords(word); } }); updateBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Word word = new Word("", ""); word.setId(269); wordViewModel.updateWords(word); } }); } void initBtnAndView(){ insertBtn = findViewById(R.id.insertBtn); updateBtn = findViewById(R.id.updateBtn); clearBtn = findViewById(R.id.clearBtn); deleteBtn = findViewById(R.id.deleteBtn); textView = findViewById(R.id.textView); } }

浙公网安备 33010602011771号