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