dependencies { def room_version = "1.1.1" implementation "android.arch.persistence.room:runtime:$room_version" annotationProcessor "android.arch.persistence.room:compiler:$room_version" // use kapt for Kotlin // optional: RxJava support for Room implementation "android.arch.persistence.room:rxjava2:$room_version" // optional: Guava support for Room, including Optional and ListenableFuture implementation "android.arch.persistence.room:guava:$room_version" // Test helpers testImplementation "android.arch.persistence.room:testing:$room_version" }
Room 有三種主要元件
- Entity: 對應到 database 的 table
- DAO: 擁有存取 database 資料的 method
- Database: 是主要存取點與 db 的持有者, 需要滿足以下要件
使用 @Database 這個 annotation 並且在裡面宣告 Entities 的 list 來定義包含的 table
繼承 RoomDatabase 的 abstract class
擁有無參數的 abstract method 可以 return 用 @Dao 標記的 Data Access Object
另外, 由於 Database 是比較耗資源的類別, 所以建議是使用 singleton 模式來獲得實體
所以一個 Database 大概會長這樣
@Database(entities = {Alarm.class}, version = 1, exportSchema = false) public abstract class XXXXXDB extends RoomDatabase { public static final String DB_NAME = "xxxxx_db"; private static XXXXXDB INSTANCE; public static XXXXXDB getInstance(final Context context){ if(INSTANCE == null){ synchronized (AlarmDB.class) { if(INSTANCE == null) { INSTANCE = Room.databaseBuilder(context, XXXXXDB.class, DB_NAME).build(); } } } return INSTANCE; } public static void destroyInstance() { if(INSTANCE != null){ INSTANCE.close(); } INSTANCE = null; } public abstract XXXXXDao xxxxxDao(); }
而 Data Access Object 則會長得像是這樣
@Dao public interface XXXXXDao { @Query("SELECT * FROM "+XXXXX.TABLE_NAME+" ORDER BY "+XXXXX.Col.TIME+" DESC" ) ListqueryXXXXXs(); @Query("SELECT * FROM "+XXXXX.TABLE_NAME+" WHERE "+XXXXX.Col.ID+" = :id") Alarm queryXXXXX(long id); @Query("SELECT * FROM "+XXXXX.TABLE_NAME+" WHERE "+XXXXX.Col.TIME+" BETWEEN :afterTheTime AND :beforeTheTime") List queryXXXXXs(long afterTheTime, long beforeTheTime); //return long (the rowId) @Insert(onConflict = OnConflictStrategy.REPLACE) long insertXXXXX(XXXXX x); @Delete void deleteXXXXX(XXXXX x); }
最後是 Entity object 的簡單範例
@Entity(tableName = XXXXX.TABLE_NAME) public class XXXXX { private static final String TAG = XXXXX.class.getSimpleName(); public static final String TABLE_NAME = "XXXXXs"; public class Col { public static final String ID = "id"; public static final String TARGET_DEVICE = "target_device_id"; public static final String ACTION = "action"; public static final String TIME = "time"; public static final String TYPE = "type"; public static final String CONTENT = "content"; } public class Value { public static final String ACTION_AAA = "aaa"; public static final String ACTION_BBB = "bbb"; } @PrimaryKey @ColumnInfo(name= Col.ID) public long id; @ColumnInfo(name= Col.TARGET_DEVICE) public String targetDeviceId; @ColumnInfo(name= Col.ACTION) public String action; @ColumnInfo(name= Col.TIME) public long time; @ColumnInfo(name= Col.TYPE) public int type; @ColumnInfo(name= Col.CONTENT) public String content; @Ignore private int[] myInts; public Alarm() { } }
另外由於檔案存取不允許在主 thread 進行
所以建議在 AsyncTask 或是 IntentService 裡面操作
相關資料:
Android Developers: Adding Components to your Project#Room
Google Developers Codelabs: Android Room with a View
Android Developers: Save data in a local database using Room
沒有留言:
張貼留言