Android Room Annotation使用简介

本文主要记录了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源码分析
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容