想必大家早用惯了SQLife这个嵌入性数据库,或是利用LitePal操作数据库。不过在我们学习MVVM时,一个更加新颖和便捷的组件进入了我们的视线——room,什么是room呢?
room定义:流畅地访问 SQLite 数据库。在SQLite上提供了一个抽象层,以在利用SQLite的全部功能的同时允许更健壮的数据库访问。
简言之就是能自动生成CUDR操作,没错,你没听错,就是自动生成,节省了我们大量开发时间。
// room
def room_version = "2.4.3"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
在我们常用的数据库里面,每个库有多张表,而每个表里有多个字段,Entity就相当于我们数据库里面的表,每个变量都要用get()和set()。
这里附上笔记项目的部分Entity示例代码:
笔记需要有标题、内容、发布时间等多个字段
@Entity
public class NoteEntity {
// 主键
@PrimaryKey(autoGenerate = true)
private int id;
// 笔记标题
@ColumnInfo(name = "note_title")
private String note_title;
// 笔记内容
@ColumnInfo(name = "note_content")
private String note_content;
// 笔记发布时间
@ColumnInfo(name = "note_time")
private String note_time;
public NoteEntity(String note_title, String note_content, String note_time) {
this.note_title = note_title;
this.note_content = note_content;
this.note_time = note_time;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNote_title() {
return note_title;
}
public void setNote_title(String note_title) {
this.note_title = note_title;
}
public String getNote_content() {
return note_content;
}
public void setNote_content(String note_content) {
this.note_content = note_content;
}
public String getNote_time() {
return note_time;
}
public void setNote_time(String note_time) {
this.note_time = note_time;
}
}
在写完Entity类后,room组件的精髓来了。Dao接口类,这里存放着对表的多种操作——CRUD,在标注完关键字后,系统就自动生成了代码,我们只需调用方法即可操作数据。
附上笔记项目中的部分Dao接口类:
@Dao
public interface NoteDao {
// 添加
@Insert
void insertNote(NoteEntity note);
// 改
@Update
void updateNote(NoteEntity note);
// 单删
@Delete
void deleteNote(NoteEntity note);
// 多删
@Delete
void deleteMoreNote(NoteEntity...notes);
// 查——显示
@Query("SELECT * FROM NoteEntity ORDER BY ID DESC")
List<NoteEntity> queryAllNote();
}
让我们回忆一下,在SQLife里,我们通过继承于SQLiteOpenHelper的自建子类对象的getWritableDatabase()
/ getReadableDatabase()
获取SQLiteDatabase 的对象,之后通过此对象底层代码中的CRUD对表数据进行操作。
此处附上笔记项目中的Database代码:
@Database(entities = {NoteEntity.class},version = 1,exportSchema = false)
public abstract class NoteDatabase extends RoomDatabase {
// 设置单例模式
private static NoteDatabase INSTANCE;
public static synchronized NoteDatabase getDatabase(Context context){
if (INSTANCE ==null){
// 三个参数:控制器,Dao工具抽象类,Database的文件名称
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),NoteDatabase.class,"Note database")
.allowMainThreadQueries().build();
}
return INSTANCE;
}
// 获取Dao,即表的操作接口实例
public abstract NoteDao getNoteDao();
}
说到MVVM,当然要使用ViewModel将逻辑操作区分出来,所以这里在ViewModel里获取Dao实例,并实现CRUD方法逻辑暴露给Activity使用。
public class HomePageViewModel extends AndroidViewModel {
// 笔记表操作接口实例
private NoteDao noteDao;
public HomePageViewModel(@NonNull Application application) {
super(application);
NoteDatabase database = NoteDatabase.getDatabase(application);
// 获取表
noteDao = database.getNoteDao();
// 查询
List<NoteEntity> noteEntities = noteDao.queryAllNote();
}
/**
* 新增笔记
*/
public void insert(NoteEntity note){
noteDao.insertNote(note);
}
/**
* 删除笔记
*/
public void delete(int id,NoteEntity note){
note.setId(id);
noteDao.deleteNote(note);
}
/**
* 更新笔记
* @param id 更新笔记的id
* @param newNote 更新笔记对象
*/
public void update(int id,NoteEntity newNote){
// 根据id进行定向更新
newNote.setId(id);
// 更新
noteDao.updateNote(newNote);
}
public List<NoteEntity> queryAll(){
return noteDao.queryAllNote();
}
}
最后,MVVM路上我也只能算个初学者,对于源码逻辑什么的也讲不明白,此文章主要将的是room基础方法的运用。当然如果有bug的地方或是可以优化的地方,还请指明。
源码地址: