1.为什么使用Room
Room 持久性库在SQlite的基础上提供了一个抽象成,让用户能够充分利用 SQLite 的强大功能的同时,获享强健的数据库访问机制.它可用来避免样板代码,还可以轻松地将 SQLite 表数据转换为 Java 对象。Room 提供 SQLite 语句的编译时检查,并且可以返回 RxJava、Flowable 和 LiveData 可观察对象,使用ROOM可以让你更简单,更流畅的操作数据库,使用简单通过注解的方式就能对数据库进行增删改查,Google工程师帮你封装了访问SqlLite的代码,使你的代码性能更高
2. Room 各组件间关系
Room 的大致使用方法如下:
-
App 通过 Room 的 Database 获取与数据库相关的数据库访问对象(DAO)。
-
然后,App 使用 DAO 从数据库中获取 Entity,并且将 Entity 的变化保存到数据库中。
-
最后,APP 使用 Entity 获取和设置数据库中表的数据。
Room 中各组件之间的关系如图2- 1Room 架构图所示:
3.使用(Java版)
3.1添加依赖
dependencies {
val room_version = "2.5.0"
implementation("androidx.room:room-runtime:$room_version")
annotationProcessor("androidx.room:room-compiler:$room_version")
// To use Kotlin annotation processing tool (kapt)
kapt("androidx.room:room-compiler:$room_version")
// To use Kotlin Symbol Processing (KSP)
ksp("androidx.room:room-compiler:$room_version")
// optional - Kotlin Extensions and Coroutines support for Room
implementation("androidx.room:room-ktx:$room_version")
// optional - RxJava2 support for Room
implementation("androidx.room:room-rxjava2:$room_version")
// optional - RxJava3 support for Room
implementation("androidx.room:room-rxjava3:$room_version")
// optional - Guava support for Room, including Optional and ListenableFuture
implementation("androidx.room:room-guava:$room_version")
// optional - Test helpers
testImplementation("androidx.room:room-testing:$room_version")
// optional - Paging 3 Integration
implementation("androidx.room:room-paging:$room_version")
}
3.2创建实体类,这里就不缀述了,大部分都知道如何创建(具体可以参考官方文档) 主要使用到
@Entity//表
@PrimaryKey(autoGenerate = true)//主键唯一,自增长
@ColumnInfo(name = "age")//优先使用这个
3.3创建Dao
@Insert
void insertWords(实体类... 实体类变量名);//10条数据
@Update
void updateWords(实体类... 实体类变量名);
//条件删除
@Delete
void deleteWords(实体类... 实体类变量名);
//全部删除
@Query("DELETE FROM 实体类")
void deleteAllWords();
//查询全部
@Query("SELECT * FROM 实体类 ORDER BY ID DESC")
LiveData<List<实体类>> getAllStudentLive();
3.2 创建数据库
@Database(entities = {实体类.class}, version = 1, exportSchema = false)
public abstract class 实体类Database extends RoomDatabase {
private static 实体类Database INSTANCE;
public static synchronized 实体类Database getDatabase(Context context) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),实体类Database.class,"实体类_database")
// .allowMainThreadQueries()//允许在主线程运行(慎用,google不推荐)
.build();
}
return INSTANCE;
}
public abstract 实体类Dao get实体类Dao();
}
3.3本地仓库统一管理类
public class LocalRoomResquestManager implements ILocalRequest, IDatabaseRequest {
private static LocalRoomResquestManager INSTANCE;
private 实体类Dao m实体类Dao;
private LiveData<List<实体类>> studentsLive;
public LocalRoomResquestManager(Context context) {
实体类Database m实体类Database = 实体类Database.getDatabase(context.getApplicationContext());
m实体类Dao = m实体类Database.get实体类Dao();
实体类Live = m实体类Dao.getAll实体类Live();
}
public static LocalRoomResquestManager getInstance(Context context) {
if (null == INSTANCE) {
synchronized (LocalRoomResquestManager.class) {
if (null == INSTANCE) {
INSTANCE = new LocalRoomResquestManager(context);
}
}
}
return INSTANCE;
}
@Override
public LiveData<List<实体类>> get实体类Live() {
return studentsLive;
}
@Override
public void insert实体类s(实体类... 实体类变量名) {
new InsertAsyncTask(实体类Dao).execute(实体类变量名);
}
@Override
public void update实体类s(实体类... 实体类变量名) {
//.....自己的执行逻辑
}
@Override
public void delete实体类s(实体类... 实体类变量名) {
//.....自己的执行逻辑
}
@Override
public void deleteAll实体类s() {
new DeleteAllAsyncTask(实体类Dao).execute();
}
static class InsertAsyncTask extends AsyncTask<实体类, Void, Void> {
private 实体类Dao m实体类Dao;
public InsertAsyncTask(实体类Dao m实体类Dao) {
this.m实体类Dao = m实体类Dao;
}
@Override
protected Void doInBackground(实体类... 实体类变量名) {
studentDao.insertWords(实体类变量名);
return null;
}
}
static class DeleteAllAsyncTask extends AsyncTask<Void, Void, Void> {
private 实体类Dao m实体类Dao;
public DeleteAllAsyncTask(实体类Dao m实体类Dao) {
this.m实体类Dao = m实体类Dao;
}
@Override
protected Void doInBackground(Void... voids) {
studentDao.deleteAllWords();
return null;
}
}
}
3.4本地仓库统一管理类viewmolde的使用
public LiveData<List<Student>> get实体类Live() {
return LocalRoomResquestManager.getInstance(application).get实体类Live();
}
public void touchoffInsertStudents(实体类... 实体类变量名) {
LocalRoomResquestManager.getInstance(application).insert实体类s(实体类变量名);
}
public void touchoffDeleteAllWords() {
LocalRoomResquestManager.getInstance(application).deleteAllStudents();
}
3.5在activiry中或者fragment中的使用,这里调用就不再赘述了
4# 解决:cannot find implementation for XXX. XXX_Impl does not exist
第一次使用Jetpack上Room架构,遇到一个问题Caused by: java.lang.RuntimeException: cannot find implementation for com.aheading.request.database.AppDatabase. AppDatabase_Impl does not exist ,就是如下这个错误:
4.1检查注解是否添加
确保注解是否都已经添加,并且确保注解内容是否正确.
4.2检查依赖是否添加
//Android官网依赖是这样的,java开发人员使用
compile "android.arch.persistence.room:runtime:$room_version"
annotationProcessor 'android.arch.persistence.room:compiler:$room_version'
//对于那些使用Kotlin的人,请尝试在应用中更改annotationProcessor为kapt
compile "android.arch.persistence.room:runtime:$room_version"
kapt "android.arch.persistence.room:compiler:$room_version"
//如果您已迁移到androidx
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:$room_version"
如果使用了kotlin项目,不要忘记在顶部引用kotlin-kapt插件
apply plugin: 'kotlin-kapt'
4.3 是否是多模块x项目
如果项目包含多个模块,在使用RoomDataBase的那个模块中,同样需要添加kapt依赖。
apply plugin: 'kotlin-kapt'
dependencies {
kapt "androidx.room:room-compiler:$room_version"
}