安卓Room持久化库@Update不起作用

27

我正在尝试使用新的Android Room库更新我的数据库,但它没有起作用。这是我的方法:

@IgnoreExtraProperties
@Entity(tableName = CarModel.TABLE_NAME,
    indices = {@Index(value = "car_name", unique = true)})
public class CarModel {

    public static final String TABLE_NAME = "cars";

    @PrimaryKey(autoGenerate = true)
    private int id;

    @ColumnInfo(name = "car_name")
    private String name;

    @ColumnInfo(name = "car_price")
    private String price;

    private String type;
    private String position;
}

主活动.java

viewModel.isCarsEmpty().observe(MainActivity.this, new Observer<Integer>() {
                    @Override
                    public void onChanged(@Nullable Integer rowCount) {
                        if (rowCount == 0) {
                            viewModel.insertItems(list);
                        } else {
                            viewModel.updateItems(list);
                        }
                    }
                });

CarViewModel.java

public LiveData<Integer> isCarsEmpty() {
    return appDatabase.carDao().isDbEmpty();
}
    public void insertItems(List<CarModel> carModels) {
    new insertCarsAsyncTask(appDatabase).execute(carModels);
}

private class insertCarsAsyncTask extends AsyncTask<List<CarModel>, Void, Void> {
    private AppDatabase db;

    public insertCarsAsyncTask(AppDatabase appDatabase) {
        db = appDatabase;
    }

    @Override
    protected Void doInBackground(List<CarModel>... params) {
        db.carDao().insertCars(params[0]);
        return null;
    }
}

public void updateItems(List<CarModel> list) {
    new updateCarsTask(appDatabase).execute(list);
}

private class updateCarsTask extends AsyncTask<List<CarModel>, Void, Void> {
    private AppDatabase db;

    public updateCarsTask(AppDatabase appDatabase) {
        db = appDatabase;
    }

    @Override
    protected Void doInBackground(List<CarModel>... params) {
        db.carDao().updateCars(params[0]);
        return null;
    }
}

CarDao.java

@Insert(onConflict = REPLACE)
void insertCars(List<CarModel> cars);

@Update
void updateCars(List<CarModel> param);

@Query("SELECT count(*) FROM " + CarModel.TABLE_NAME)
LiveData<Integer> isDbEmpty();

我进行了调试,有新数据传入并调用了viewModel.updateItems(list)方法。提前感谢!

3个回答

38

确保您要更新的行和您发送更新的模型具有相同的 ID,该 ID 是您定义为主键的。


一个非常简单而有用的答案。 - Amir

9

很抱歉我以回答的形式发布此内容,但我还无法添加简单评论,所以这是我的想法:

您是否尝试仅使用insertCars()而不是updateCars()?无论如何,看起来您的isCarsEmpty() LiveData回调一直被触发,因为当观察者被调用时,数据库再次被修改.. 我不太确定您想要实现什么。


很好的想法,只有insertCars()函数能够实现我想要的效果。再次感谢您。 - nAkhmedov
很高兴我能帮到你 :) - maperz
1
我在使用 onConflict = OnConflictStrategy.REPLACE 插入实体时遇到了问题,该实体具有 @PrimaryKey(autoGenerate = true),结果新的 ID 被插入而不是更新具有相同 ID 的条目。有什么建议吗? - etomun
@etomun 如果你设置了 autoGenerate=true,那么你首先需要获取要更新的实体,然后使用该实体的 ID 来构建新实体。 - dumbfingers
@dumbfingers 好的,所以我需要两个数据库操作,对吧? - etomun
1
autoGenerate=true 的情况下,是的。 - dumbfingers

0

更新意味着您获取已经在数据库中的CarModel,并在更新此CarModel后将新值返回到数据库,除了Id之外,您返回相同的Id

该怎么做

例如,您需要一个类型为CarModel的全局变量,并在CarModel中实现设置函数

在MainActivity中,将获取的CarModel分配给全局变量,并使用set函数更新CarModel的成员变量的值

然后将此全局变量传递给MainActivity中的更新函数

我在我的Github上有类似的示例


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接