Android Room Annotation使用简介

作者: tianbin | 来源:发表于2017-08-17 16:40 被阅读670次

本文主要记录了Room Persistence Library中注解的使用方法。代码已上传到Github,欢迎star,fork

架构示意图

如下图


添加依赖

compile "android.arch.persistence.room:runtime:1.0.0-alpha5"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha5"

准备工作

Create Model

@Entity
public class Library {

    @PrimaryKey(autoGenerate = true)
    public int id;
    @ColumnInfo(name = "library_name")
    public String name;
    
    @Embedded
    public Address address;
}
public clas Address {

    public String city;
    public String street;

    @ColumnInfo(name = "post_code")
    public int postCode;
}

Create Dao

@Dao
public interface LibraryDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insert(Library library);
}

Create Database

@Database(entities = {Library.class}, version = 1)
public abstract class LibraryDatabase extends RoomDatabase {

    public abstract LibraryDao libraryDao();
}

Init Database

public class RoomApplication extends Application {

    private LibraryDatabase mLibraryDatabase;

    @Override
    public void onCreate() {
        super.onCreate();
      
        mLibraryDatabase = Room.databaseBuilder(getApplicationContext(),
                LibraryDatabase.class, "library").build();

        new Thread() {
            @Override
            public void run() {
                super.run();

                final Library library = new Library();
                library.name = "library 1";
               final Address address = new Address();
                address.city = "beijing";
                address.street = "shang di dong lu";
                address.postCode = 11111;
                library.address = address;
                mLibraryDatabase.libraryDao().insert(library);
            }
        }.start();
    }
}

结果为下图:

表中出现的两个id,其中一个是Room自动添加的,以下是Room生成的建表语句

_db.execSQL("CREATE TABLE IF NOT EXISTS `Library` (`id` INTEGER, `library_name` TEXT,`address` TEXT, PRIMARY KEY(`id`))");

Annotations的使用

Entity

@Entity

  • 使用注解之外的另一种定义主键的方式

    @Entity(primaryKeys = {"firstName", "lastName"})

  • 为列添加索引

    @Entity(indices = {@Index("name"),@Index(value = {"last_name", "address"})})

  • 定义外键

    @Entity(foreignKeys = @ForeignKey(entity = User.class,
                                      parentColumns = "id",
                                      childColumns = "user_id",
                                      onDelete = CASCADE))
    
  • 自定义表名,默认使用类名为表名

    @Entity(tableName = "users")

@PrimaryKey

@PrimaryKey(autoGenerate = true)

定义主键,并设置是否自动增长

@ColumnInfo

@ColumnInfo(name = "library_name")

自定义数据库表结构中该字段的列名

@Ignore

用来标记不需要持久化的字段

@Embedded

用来处理model嵌套的情况,如Library 中包含 Address

@ForeignKey

为model添加外键,建立对象之间的所属关系,也可以通过@Relation来实现

添加onDelete = CASCADE可以在进行级联删除,简单讲就是,如果删除了某条library数据,那么与之关联的category数据和与category数据关联的book数据,都会被删除

Dao

@Dao

标注Entity对应的Dao类(接口),Room会为它生成实现类

@Insert

@Insert(OnConflict=REPLACE)

被标注的方法只能返回 voidlongLonglong[]Long[]或者List<Long>

@Update

被标注的方法只能返回voidint

@Delete

被标注的方法只能返回voidint

@Query

@Query注解是DAO类中最主要的注解,被用来执行数据库的读写操作。每一个被标注的方法都会在编译时被检查,如果查询方法存在语法错误或者数据库不存在该表,Room会给出对应的编译错误。

  • 简单查询

    @Dao
    public interface LibraryDao {
    
        @Query("SELECT * FROM library")
        List<Library> query();
    }
    
  • 带参数查询

    @Dao
    public interface LibraryDao {
    
        @Query("SELECT * FROM library WHERE library_name = :name")
        Library query(String name);
    }
    
  • 只返回某些列

    public class LibraryAddressName {
    
        @ColumnInfo(name = "library_name")
        public String libraryName;
        @ColumnInfo(name = "city")
        public String city;
    }
    
    @Dao
    public interface LibraryDao {
    
        @Query("SELECT library_name,city FROM library")
        List<LibraryAddressName> queryLibraryAddressName();
    }
    
  • 带一组参数

    @Dao
    public interface LibraryDao {
    
        @Query("SELECT * FROM library WHERE city IN (:cityList)")
        List<Library> queryByCityName(List<String> cityList);
    }
    
  • 返回LiveData形式的结果

    @Dao
    public interface LibraryDao {
    
        @Query("SELECT * FROM library")
        LiveData<List<Library>> queryReturnLiveData();
    }
    
  • 返回Flowable形式的结果

    @Dao
    public interface LibraryDao {
    
        @Query("SELECT * FROM library")
        Flowable<List<Library>> queryReturnFlowable();
    }
    
  • 返回Cursor(不推荐

    @Dao
    public interface LibraryDao {
    
        @Query("SELECT * FROM library")
        Cursor queryReturnCursor();
    }
    
  • 多表查询

    @Dao
    public interface LibraryDao {
    
        @Query("SELECT * FROM library "
                + "INNER JOIN category ON category.library_id = library.id "
                + "INNER JOIN book ON book.category_id = category.id "
                + "WHERE book.name LIKE :bookName")
        Library findLibraryByBookName(String bookName);
    }
    

Database

@Database

@Database(entities = {User.java}, version = 1)

定义数据库中包含的表,数据库版本

@TypeConverter

将Entity中字段类型进行转换后再持久化,可以选择范围,文档说明如下:

  • If you put it on a Database, all Daos and Entities in that database will be able to use it.
  • If you put it on a Dao, all methods in the Dao will be able to use it.
  • If you put it on an Entity, all fields of the Entity will be able to use it.
  • If you put it on a POJO, all fields of the POJO will be able to use it.
  • If you put it on an Entity field, only that field will be able to use it.
  • If you put it on a Dao method, all parameters of the method will be able to use it.
  • If you put it on a Dao method parameter, just that field will be able to use it.

POJO

@Relation

用于多表联查,Room会将查询结果中的数据对应到Pojo实例。

@Dao
public interface LibraryDao {

    @Query("SELECT * FROM library")
    List<LibraryCategoryBook> queryByRelation();
}

public class LibraryCategoryBook {

    @Embedded
    public Library library;

    @Relation(parentColumn = "id", entityColumn = "library_id", entity = Category.class)
    public List<CategoryBook> categoryList;

    public static class CategoryBook {
        @Embedded
        public Category category;

        @Relation(parentColumn = "id", entityColumn = "category_id")
        public List<Book> bookList;
    }
}

以上Dao类中的方法都提供了测试方法,见Github

后续

  • 数据库版本升级及迁移
  • RxJava & Room
  • Room源码分析

相关文章

网友评论

    本文标题:Android Room Annotation使用简介

    本文链接:https://www.haomeiwen.com/subject/jjlnrxtx.html