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" )
List queryXXXXXs();
@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
沒有留言:
張貼留言