Android-Jetpack中Room使用

7 Nov 2018

最近在学习使用jetpack里的组件,本项目学习Room模块。
Room是数据库框架,更方便、简单地操作数据库。

相关文档:

Room官方说明:
https://developer.android.com/topic/libraries/architecture/room
Room官方文档:
https://developer.android.com/training/data-storage/room/
Room实例教学:
https://codelabs.developers.google.com/codelabs/android-room-with-a-view/#0
Room实例代码:
https://github.com/googlecodelabs/android-room-with-a-view
本文章代码:
https://github.com/pulque/WordNotes

类说明:

1.WelcomeActivity

开始页面,显示文字列表。添加按钮打开添加页面。

2.NewWordActivity

添加文字页面,点击保存,把文字返回给列表页面进行添加。

3.WordViewModel

缓存数据,并监听数据变化。

4.WordListAdapter

列表适配器,使用RecyclerView展示数据。

5.WordRoomDatabase

数据库创建类,并提供操作Dao的实例。

6.WordRepository

通过WordRoomDatabase提供的Dao实例,操作数据,查询、插入等。

7.WordDao

提供表操作的接口,包含数据库执行语句。

8.Word

表结构定义对象。

Room相关类详细说明:

1.Word

@Entity(tableName = "word_table")
public class Word {

    @PrimaryKey
    @NonNull
    @ColumnInfo(name = "word")
    private String mWord;
    @NonNull
    @ColumnInfo(name = "chinese")
    private String mChinese;

    public Word(@NonNull String word, @NonNull String chinese) {
        this.mWord = word;
        this.mChinese = chinese;
    }

    public String getWord() {
        return this.mWord;
    }

    public String getChinese() {
        return mChinese;
    }
}
解释:
@Entity在数据库中表的名字。
@PrimaryKey主键
@ColumnInfo在表中字段的名字
GET方法必须定义,数据库需要此方法对变量进行操作。

2.WordDao

@Dao
public interface WordDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insert(Word word);

    @Query("DELETE FROM word_table")
    void deleteAll();

    @Query("SELECT * from word_table ORDER BY word ASC")
    LiveData<List<Word>> getAllWords();
}
解释:
@Dao表操作标识。
@Insert插入操作,可以不提供执行语句。
@Query语句执行标识,需添加执行语句。

3.WordRoomDatabase

去掉添加默认数据部分。
@Database(entities = {Word.class}, version = 1)
public abstract class WordRoomDatabase extends RoomDatabase {

    private static volatile WordRoomDatabase INSTANCE;

    static WordRoomDatabase getDatabase(final Context context) {
        if (INSTANCE == null) {
            synchronized (WordRoomDatabase.class) {
                if (INSTANCE == null) {
                    // Create database here
                    INSTANCE = Room.databaseBuilder(
                            context.getApplicationContext(),
                            WordRoomDatabase.class, "word_database")
                            .build();
                }
            }
        }
        return INSTANCE;
    }

    public abstract WordDao wordDao();
}
解释:
@Database标识所包含的表喝数据库版本等信息。
创建数据库,并保存单例,提供表操作接口。

4.WordRepository

数据异步操作,为WordViewModel提供数据支持。
public class WordRepository {

    private WordDao mWordDao;
    private LiveData<List<Word>> mAllWords;

    public WordRepository(Application application) {
        WordRoomDatabase db = WordRoomDatabase.getDatabase(application);
        mWordDao = db.wordDao();
        mAllWords = mWordDao.getAllWords();
    }

    public LiveData<List<Word>> getAllWords() {
        return mAllWords;
    }

    public void insert(Word word) {
        new insertAsyncTask(mWordDao).execute(word);
    }

    private static class insertAsyncTask 
                   extends AsyncTask<Word, Void, Void> {

        private WordDao mAsyncTaskDao;

        insertAsyncTask(WordDao dao) {
            mAsyncTaskDao = dao;
        }

        @Override
        protected Void doInBackground(final Word... params) {
            mAsyncTaskDao.insert(params[0]);
            return null;
        }
    }
}
解释:
使用AsyncTask进行异步操作。
使用Dao进行表数据操作。

总结:

WordRepository通过数据库WordRoomDatabase提供的WordDao,
给WordViewModel提供数据。
WordViewModel通知UI进行数据显示更新。

进阶:

使用RxAndroid2代替AsyncTask进行异步操作。
Room复杂操作。
进阶参考:
https://github.com/googlesamples/android-architecture-components/
https://codelabs.developers.google.com/?cat=Android