本文主要記錄了Room Persistence Library中注解的使用方法。代碼已上傳到Github,歡迎star,fork
架構(gòu)示意圖
如下圖

添加依賴
compile "android.arch.persistence.room:runtime:1.0.0-alpha5"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha5"
準(zhǔn)備工作
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();
}
}
結(jié)果為下圖:

表中出現(xiàn)的兩個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)) -
自定義表名,默認(rèn)使用類名為表名
@Entity(tableName = "users")
@PrimaryKey
@PrimaryKey(autoGenerate = true)
定義主鍵,并設(shè)置是否自動增長
@ColumnInfo
@ColumnInfo(name = "library_name")
自定義數(shù)據(jù)庫表結(jié)構(gòu)中該字段的列名
@Ignore
用來標(biāo)記不需要持久化的字段
@Embedded
用來處理model嵌套的情況,如Library 中包含 Address
@ForeignKey
為model添加外鍵,建立對象之間的所屬關(guān)系,也可以通過@Relation來實現(xiàn)
添加onDelete = CASCADE可以在進(jìn)行級聯(lián)刪除,簡單講就是,如果刪除了某條library數(shù)據(jù),那么與之關(guān)聯(lián)的category數(shù)據(jù)和與category數(shù)據(jù)關(guān)聯(lián)的book數(shù)據(jù),都會被刪除
Dao
@Dao
標(biāo)注Entity對應(yīng)的Dao類(接口),Room會為它生成實現(xiàn)類
@Insert
@Insert(OnConflict=REPLACE)
被標(biāo)注的方法只能返回 void,long,Long,long[],Long[]或者List<Long>
@Update
被標(biāo)注的方法只能返回void,int
@Delete
被標(biāo)注的方法只能返回void,int
@Query
@Query注解是DAO類中最主要的注解,被用來執(zhí)行數(shù)據(jù)庫的讀寫操作。每一個被標(biāo)注的方法都會在編譯時被檢查,如果查詢方法存在語法錯誤或者數(shù)據(jù)庫不存在該表,Room會給出對應(yīng)的編譯錯誤。
-
簡單查詢
@Dao public interface LibraryDao { @Query("SELECT * FROM library") List<Library> query(); } -
帶參數(shù)查詢
@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(); } -
帶一組參數(shù)
@Dao public interface LibraryDao { @Query("SELECT * FROM library WHERE city IN (:cityList)") List<Library> queryByCityName(List<String> cityList); } -
返回LiveData形式的結(jié)果
@Dao public interface LibraryDao { @Query("SELECT * FROM library") LiveData<List<Library>> queryReturnLiveData(); } -
返回Flowable形式的結(jié)果
@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)
定義數(shù)據(jù)庫中包含的表,數(shù)據(jù)庫版本
@TypeConverter
將Entity中字段類型進(jìn)行轉(zhuǎn)換后再持久化,可以選擇范圍,文檔說明如下:
- 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
Entityfield, only that field will be able to use it. - If you put it on a
Daomethod, all parameters of the method will be able to use it. - If you put it on a
Daomethod parameter, just that field will be able to use it.
POJO
@Relation
用于多表聯(lián)查,Room會將查詢結(jié)果中的數(shù)據(jù)對應(yīng)到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
后續(xù)
- 數(shù)據(jù)庫版本升級及遷移
- RxJava & Room
- Room源碼分析