我是Room Database的新用户,最近我遇到了一个问题,该问题与修改应用程序的数据库(更新/插入/删除)有关,而不会导致触发观察器中的回调。
这是我的模型的Dao
类:
@Dao
interface ReceiptRowDao {
@Query("SELECT * FROM my_model ")
fun getMyModels(): LiveData<MutableList<MyModel>>
@Update
fun update(receiptRow: ReceiptRow): Int
}
我的Database
班:
@Database(
entities = [
(MyModel::class)
],
version = 1,
exportSchema = false
)
abstract class AppDatabase: RoomDatabase() {
abstract fun myModelDao(): MyModelDao
}
用法:
class MyClass {
val db: AppDatabase = Room
.databaseBuilder(mContext, AppDatabase::class.java, "my_db")
.allowMainThreadQueries()
.build()
fun test() {
val myLiveData = db.myModelDao.getMyModels()
myLiveData!!.observe(this, Observer { data ->
...
val item = data.get(0)
item.id = 4
// This update should not cause a callback
db.myModelDao().update(item)
...
})
}
}
在MyClass
中,更新指令将导致无限循环,因为对MyModel的更新将触发观察者。然后,观察者内部的代码将再次运行。这将进行另一次更新。这将再次触发观察者,依此类推...
在这种情况下,是否有一种方法可以进行模型更新,但是可以跳过可能正在监听更改的观察者?
答案 0 :(得分:0)
我认为您可以做的只是简单地检查数据库中是否已存在data
。喜欢
fun test() {
val myLiveData = db.myModelDao.getMyModels()
myLiveData!!.observe(this, Observer { data ->
...
val item = data.get(0);
// This update should not cause a callback
if (!db.myModelDao().itemExists(item){
db.myModelDao().update(item)
}
...
})
}
答案 1 :(得分:0)
这是保存DAO类及其实例的数据库类
@Database(entities = {Weight.class, DailyConsumption.class, DrinkType.class}, version = 1, exportSchema = false)
public abstract class MyDataBase extends RoomDatabase {
// DAO classes
public abstract WeightDao weightDao();
public abstract DailyConsumptionDao dailyConsumptionDao();
public abstract DrinkTypeDao drinkTypeDao();
private static MyDataBase dataBase;
public static MyDataBase getInstance(Context context){
if (null== dataBase){
dataBase= buildDatabaseInstance(context);
}
return dataBase;
}
private static MyDataBase buildDatabaseInstance(Context context) {
return Room.databaseBuilder(context,
MyDataBase.class,
Constants.DB_NAME)
.allowMainThreadQueries().build();
}
}
,要在数据库中插入数据的部分带有两个参数。一个数据库类对象和实体。我已将实体类设计为类似于模型类,可用于在主类中设置和获取值。
dailyConsumption = new DailyConsumption(); // entity class
myDataBase = MyDataBase.getInstance(this);
dailyConsumption.setIcon(mIcon);
dailyConsumption.setQuantity(mQuantity);
dailyConsumption.setTime(strTime);
dailyConsumption.setIsSelected(0);
dailyConsumption.setDrinkUnit(drinkUnit);
dailyConsumption.setDateTime(insertionDate);
dailyConsumption.setDate(date);
setDailyDataBase(myDataBase, dailyConsumption);
和方法setDailyDatabase只是调用数据库类以插入实体
private void setDailyDataBase(MyDataBase dataBase, DailyConsumption dailyConsumption) {
// query takes parameters to update respective columns
myDataBase.dailyConsumptionDao().updateItem(mId, mQuanity, mTime, date);
}
答案 2 :(得分:0)
对于您的问题,我建议您按照以下方式观察LiveData
和更新Model
:
class MyClass {
val db: AppDatabase = Room
.databaseBuilder(mContext, AppDatabase::class.java, "my_db")
.allowMainThreadQueries()
.build()
fun getDataObserver() = db.myModelDao.getMyModels()
fun test(item: MyModel) {
db.myModelDao().update(item)
}
}
这将帮助您将观察者逻辑与更新逻辑分开,现在调用getDataObserver()
方法,在其中您要观察数据并使用test()方法当您想更新模型时。