web-dev-qa-db-ja.com

Android Room永続ライブラリ@Updateが機能しない

新しいAndroidルームライブラリ)を介してデータベースを更新しようとしていますが、機能していません。これが私のアプローチです

@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;
}

MainActivity.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)メソッドを呼び出します。

14
nAkhmedov

これを回答として投稿して申し訳ありませんが、簡単なコメントの追加はまだ許可されていないため、ここに私の考えを示します。

insertCars()の代わりにupdateCars()のみを使用してみましたか?とにかく、オブザーバーが呼び出されると、データベースが再度変更されるため、isCarsEmpty() LiveDataコールバックが常にトリガーされるように見えます。達成したいことはよくわかりません。

6
Maperz

更新する行と更新に送信するモデルに、主キーとして定義したものと同じIDが含まれていることを確認してください。

12
Kimmi Dhingra

更新とは、データベースにすでに存在するCarModelをフェッチし、このCarModelを更新した後、同じ値を返すIDを除いて、データベースに新しい値を返すことを意味します

何をすべきか

たとえば、タイプCarModelのグローバル変数が必要であり、CarModelにセット関数を実装する

MainActivityで、フェッチしたCarModelをグローバル変数に割り当て、set関数を使用してCarModelのメンバー変数の値を更新します

次に、このグローバル変数をMainActivityの更新関数に渡します

私のGithubにこのような例があります

0
moamarubuntu