Room数据库详实使用指北(附Demo)

简介

​Room是Google官方推出的Architecture Components中的一个持久性数据库,提供了基于SQLite的抽象层,可以在充分利用SQLite功能的前提下流畅的访问数据库。(官方详细介绍,需要翻墙)

相信早期使用过SQLite进行开发的小伙伴都深有体会SQLite使用起来有多麻烦:SQLite没有提供编译时的sql检查机制,即使写错了也可以通过编译,需要在编译出来之后去验证,同时,在进行CRUD操作时需要手动写很多sql与bean之前转换的无脑式代码,费时费力。

所以后面催生出了很多类似于greenDao、Realm等优秀的第三方开源数据库框架,但终究不是官方的,全靠个人在升级维护,在考虑便捷性、性能以及后期升级拓展等方面因素的情况下,个人觉得Room还是挺不错的一个选择,毕竟有Google的研发团队在支撑。扯远了哈,这都是题外话了,下面我们来看看Room有什么优点。

优点
  • 编译时检查。Room会在编译期去检查验证sql的正确性,这样就不会出现运行时出现严重错误的风险;
  • 使用便捷。只需简单的三步少量的代码即可实现常规的CDUR;
  • 支持LiveData;
  • 与Rxjava结合可以实时监听数据变化。
Demo效果及地址

Demo中包括了常见的增、删、改、查以及数据库升级等功能,还包括了结合Rxjava监听数据变化的功能。
在这里插入图片描述
Demo地址:https://github.com/jianlin00000/RoomDemo

创建步骤
添加依赖

在app/build.gradle中添加如下依赖:

	//运行时和编译时依赖
	implementation 'android.arch.persistence.room:runtime:1.1.1'
    annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'
    //支持Rxjava2
    implementation 'android.arch.persistence.room:rxjava2:1.1.1'
    //测试支持
    androidTestImplementation 'android.arch.persistence.room:testing:1.1.1'

1.使用@Entity创建表
@Entity(tableName = "student") //设置表名
public class Student {
    
    @NonNull //主键不能为null,必须添加这个注解
    @PrimaryKey(autoGenerate = true) //主键是否自动增长,默认为false
    public long id;
    
    @ColumnInfo 
    public int age;
    
    @ColumnInfo(name = "name") //可以通过设置name =xxx 的方式重新命名字段
    public String studentName;
    
	@ColumnInfo 
    public int age;

    @Embedded 
    public CourseScore course;
    
   public Student() {
    }
    

    @Ignore //只允许有一个主构造方法,其他构造方法要使用@Ignore设置为忽略
    public Student(@NonNull int id, int age, String name, CourseScore course) {
        this.id = id;
        this.age = age;
        this.name = name;
        this.course = course;
    }
}
public class CourseScore {

	public int chinese;
    public int english;
    public int math;
    @Ignore
	public int sports;  //这个字段将被忽略,不会被映射到表中
	
    public CourseScore(int chinese, int english, int math) {
        this.chinese = chinese;
        this.english = english;
        this.math = math;
    }
}

说一下类中出现的几个注解的意思:

@Entity

在Room中每个表对应一个具有 @Entity 注解的JavaBean,也就是说一个bean对应一张表;

@PrimaryKey

所有的CRUD操作都是根据主键进行操作的,所以每个表要求必须有一个主键,主键字段通过 @PrimaryKey 进行标识,因为主键不能为空,所以要求必须添加android.support.annotation注解库中的 @NonNull 注解 ,否则编译报错。主键默认是不自增,因为主键的类型并不限于long、int等类型,String等类型也是可以的;

@ColumnInfo

bean中每一个具有@ColumnInfo 注解的字段会被映射为表中的一个字段,映射字段可以更改,默认直接使用当前字段,另外如果字段为private修饰的则必须提供对应的getter、setter方法,public字段修饰则不用;

@Ignore

顾名思义,该注解是用于设置忽略的,每个表对应的JavaBean只能有一个主构造方法,若还有其它的构造方法则必须使用@Ignore注解进行标识;

@Embedded

这也是一个很方便实用的注解,这个注解可以将普通JavaBan中的字段也引入到对应的表中,查询结果会自动为对应的bean,不需要的字段可以使用@Ignore进行标识

2.使用@Dao,创建操作数据库的接口
@Dao
public interface StudentDao {

    //-------------------------插入--------------------------------------------
    
    /**
     * 插入操作,若已存在相同的主键的数据则直接覆盖
     *  返回值也可以设为void
     * @param student
     * @return 插入的row id
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    Long insert(Student student);

    /**
     * 同上
     * @param student
     * @return 插入的row id 集合,也可以设置为Long[]返回值
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    List<Long> insert(Student ... student);

    /**
     * 同上
     * @param list
     * @return 插入的row id 集合
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    List<Long> insert(List<Student> list);

    //-------------------------更新--------------------------------------------

    /**
     * 更新操作
     * @param student
     * @return 更新成功的数量
     */
    @Update
    int update(Student student);

    /**
     * 同上
     * @param student
     * @return 更新成功的数量
     */
    @Update
    int update(Student... student);


    //-------------------------查询--------------------------------------------

   /**
     * 查询指定名字的数据
     * @param name
     * @return
     */
    @Query("SELECT * FROM student WHERE name=:name")
    Student getByName(String name);

    /**
     * 查询所有数据
     * @return
     */
    @Query("SELECT * FROM student")
    List<Student> loadAll();

    /**
     * 查询所有数据
     *  与Rxjava的Flowable结合,可以进行数据变化监听
     * @return
     */
    @Query("SELECT * FROM student")
    Flowable<List<Student>> getAll();

    //-------------------------删除--------------------------------------------
    
    /**
     * 根据主键进行删除
     * @param student
     * @return 删除成功的数量
     */
    @Delete
    int delete(Student student);

    @Delete
    int delete(Student... student);

    @Query("DELETE FROM student")
    int deleteAll();

    /**
     * 删除指定名字的数据
     * @param name
     * @return
     */
    @Query("DELETE FROM student where name=:name")
    int deleteByName(String name);

}

到这一步可以说已经完成了将近80%了,是不是很便捷,我们来看一下DAO类中出现的一些注解:

@Dao

DAO是数据库访问对象,要变成一个数据库访问对象必须在类的声明上面添加 @Dao 注解,并且根据官方文档的要求,DAO必须是一个interface 或者 abstract class,然后在里面写操作数据库的相关接口,主要的是通过在方法上添加 @Insert、@Update、@Query、@Delete中的某一个注解实现对应的“插入、更新、查询、删除”操作。注意,DAO类中这些操作都是阻塞的,使用要在异步线程中使用。

@Insert

插入操作中出现了 “@Insert(onConflict =

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值