Android应用框架之数据库框架Room简介

痞子三分冷 提交于 2019-11-28 08:27:36

Room是什么

Room是Android官方提供的一个数据库框架,对Sqlite进行了一层抽象和封装,最开始Google出于对Android应用架构生态的考虑,作为应用架构的一部分开发了这个库,目前依然在维护和优化,不过已经从原来的仓库迁移到了androidx系列组件下面。所以,后来者建议从androidx开始。

Room的版本

  1. 老版本,即Pre-androidx版本
    包路径:android.arch.persistence.room

  2. 新版本,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();
}

这里有几个关注点:

  1. 使用@Database注解修饰抽象类
  2. 通过@Database注解的entities参数,可以声明此数据库中需要创建的表,每张表映射具体的类,这里对应Task
  3. 定义一个抽象方法,返回DAO对象
  4. 数据库的版本也可以通过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);
    }
	
}

同样有几个关注点:

  1. @Entity注解,用于修饰实体类,参数tableName定义表名
  2. @ColumnInfo注解,定义表字段,可选的,定义表字段名
  3. @PrimaryKey注解,用于声明主键
  4. @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();
}

几个关注点:

  1. @Query注解,用于查询操作,可以返回单个对象或者对象列表,数组应该也支持
  2. @Insert注解,用于插入操作,参数为列表,可以支持批量插入。插入方法是否支持返回值,待验证
  3. @Update注解,用于更新操作,可以通过WHERE条件,更新单条或者多条数据
  4. @Delete注解,用于删除操作,可以通过WHERE条件,删除单条或者多条数据
  5. @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的简单理解,只能算入门介绍,谈不上深入理解,后面有新的理解了,我会继续发文章跟大家分享。文中有理解不对的地方,欢迎指正。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!