本文主要記錄了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)
被标注的方法隻能傳回 void,long,Long,long[],Long[]或者List
@Update
被标注的方法隻能傳回void,int
@Delete
被标注的方法隻能傳回void,int
@Query
@Query注解是DAO類中最主要的注解,被用來執行資料庫的讀寫操作。每一個被标注的方法都會在編譯時被檢查,如果查詢方法存在文法錯誤或者資料庫不存在該表,Room會給出對應的編譯錯誤。
簡單查詢
@Dao
public interface LibraryDao {
@Query("SELECT * FROM library")
List 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 queryLibraryAddressName();
}
帶一組參數
@Dao
public interface LibraryDao {
@Query("SELECT * FROM library WHERE city IN (:cityList)")
List queryByCityName(List cityList);
}
傳回LiveData形式的結果
@Dao
public interface LibraryDao {
@Query("SELECT * FROM library")
LiveData> queryReturnLiveData();
}
傳回Flowable形式的結果
@Dao
public interface LibraryDao {
@Query("SELECT * FROM library")
Flowable> 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 queryByRelation();
}
public class LibraryCategoryBook {
@Embedded
public Library library;
@Relation(parentColumn = "id", entityColumn = "library_id", entity = Category.class)
public List categoryList;
public static class CategoryBook {
@Embedded
public Category category;
@Relation(parentColumn = "id", entityColumn = "category_id")
public List bookList;
}
}
以上Dao類中的方法都提供了測試方法,見Github
後續
資料庫版本更新及遷移
RxJava & Room
Room源碼分析