Room是什么
Room是Android官方提供的一个数据库框架,对Sqlite进行了一层抽象和封装,最开始Google出于对Android应用架构生态的考虑,作为应用架构的一部分开发了这个库,目前依然在维护和优化,不过已经从原来的仓库迁移到了androidx系列组件下面。所以,后来者建议从androidx开始。
Room的版本
-
老版本,即Pre-androidx版本
包路径:android.arch.persistence.room -
新版本,androidx版本
包路径:androidx.room
怎么用
因为本人在实际项目中暂未集成该数据库,只是对android-architecture官方demo作了一下研究,这里先跟大家简单分享一下Pre-androidx版本的入门使用,使用跟androidx应该大差不差。
有兴趣的同学参考android-architecture中的代码:
git clone https://github.com/googlesamples/android-architecture.git
1、添加依赖
dependencies {
compile "android.arch.persistence.room:runtime:1.0.0"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"
}
2、创建一个抽象类,继承RoomDatabase
@Database(entities = {Task.class}, version = 1)
public abstract class ToDoDatabase extends RoomDatabase {
public abstract TasksDao taskDao();
}
这里有几个关注点:
- 使用@Database注解修饰抽象类
- 通过@Database注解的entities参数,可以声明此数据库中需要创建的表,每张表映射具体的类,这里对应Task
- 定义一个抽象方法,返回DAO对象
- 数据库的版本也可以通过version参数设置
3、创建一个实体类,映射数据表
@Entity(tableName = "tasks")
public final class Task {
@PrimaryKey
@NonNull
@ColumnInfo(name = "entryid")
private final String mId;
@Nullable
@ColumnInfo(name = "title")
private final String mTitle;
@Nullable
@ColumnInfo(name = "description")
private final String mDescription;
@ColumnInfo(name = "completed")
private final boolean mCompleted;
@Ignore
public Task(@Nullable String title, @Nullable String description) {
this(title, description, UUID.randomUUID().toString(), false);
}
}
同样有几个关注点:
- @Entity注解,用于修饰实体类,参数tableName定义表名
- @ColumnInfo注解,定义表字段,可选的,定义表字段名
- @PrimaryKey注解,用于声明主键
- @Ignore注解,用于标记Room应该忽略的属性和方法,对于未标记@Ignore的属性,默认会被持久化
当然,这里我只列了一个构造函数,你还可以添加其他方法。
4、创建DAO接口类
@Dao
public interface TasksDao {
@Query("SELECT * FROM Tasks")
List<Task> getTasks();
@Query("SELECT * FROM Tasks WHERE entryid = :taskId")
Task getTaskById(String taskId);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertTask(Task task);
@Update
int updateTask(Task task);
@Query("UPDATE tasks SET completed = :completed WHERE entryid = :taskId")
void updateCompleted(String taskId, boolean completed);
@Query("DELETE FROM Tasks WHERE entryid = :taskId")
int deleteTaskById(String taskId);
@Delete("DELETE FROM Tasks")
void deleteTasks();
@Query("DELETE FROM Tasks WHERE completed = 1")
int deleteCompletedTasks();
}
几个关注点:
- @Query注解,用于查询操作,可以返回单个对象或者对象列表,数组应该也支持
- @Insert注解,用于插入操作,参数为列表,可以支持批量插入。插入方法是否支持返回值,待验证
- @Update注解,用于更新操作,可以通过WHERE条件,更新单条或者多条数据
- @Delete注解,用于删除操作,可以通过WHERE条件,删除单条或者多条数据
- @Query注解除了查询功能外,还支持增删改操作,用法基本一样,只是它的返回值支持void和int类型。
5、创建RoomDatabase数据库操作对象
ToDoDatabase database = Room.databaseBuilder(context.getApplicationContext(),
ToDoDatabase.class, "Tasks.db")
.build();
6、增删改查实例
下面就以android-architecture中mvp分支中的实现为例,看下增删改查的使用:
public class TasksLocalDataSource implements TasksDataSource {
// DAO对象
private TasksDao mTasksDao;
// 线程池帮助类,这里不用详细关注
private AppExecutors mAppExecutors;
private TasksLocalDataSource(@NonNull AppExecutors appExecutors,
@NonNull TasksDao tasksDao) {
mAppExecutors = appExecutors;
mTasksDao = tasksDao;
}
@Override
public void getTasks(@NonNull final LoadTasksCallback callback) {
Runnable runnable = new Runnable() {
@Override
public void run() {
final List<Task> tasks = mTasksDao.getTasks();
mAppExecutors.mainThread().execute(new Runnable() {
@Override
public void run() {
if (tasks.isEmpty()) {
// This will be called if the table is new or just empty.
callback.onDataNotAvailable();
} else {
callback.onTasksLoaded(tasks);
}
}
});
}
};
mAppExecutors.diskIO().execute(runnable);
}
@Override
public void saveTask(@NonNull final Task task) {
checkNotNull(task);
Runnable saveRunnable = new Runnable() {
@Override
public void run() {
mTasksDao.insertTask(task);
}
};
mAppExecutors.diskIO().execute(saveRunnable);
}
@Override
public void completeTask(@NonNull final Task task) {
Runnable completeRunnable = new Runnable() {
@Override
public void run() {
mTasksDao.updateCompleted(task.getId(), true);
}
};
mAppExecutors.diskIO().execute(completeRunnable);
}
@Override
public void clearCompletedTasks() {
Runnable clearTasksRunnable = new Runnable() {
@Override
public void run() {
mTasksDao.deleteCompletedTasks();
}
};
mAppExecutors.diskIO().execute(clearTasksRunnable);
}
}
上面对于增删改查分别列了一个使用方法,都是在IO线程去执行数据库操作的,其中查询方法提供了主线程回调功能。
另外,对于数据库操作,有实时和时序要求的,使用时还要做进一步处理。
小结
以上就是本人对Room的简单理解,只能算入门介绍,谈不上深入理解,后面有新的理解了,我会继续发文章跟大家分享。文中有理解不对的地方,欢迎指正。