数据未正常更新(房间数据库)
Data is not updated normally (room database)
我需要在刷新页面时向 API
发出请求并将获取数据插入我的房间数据库。但是当我尝试插入数据时,我得到 io.reactivex.exceptions.OnErrorNotImplementedException: UNIQUE constraint failed: data.id (code 1555).
所以我决定检查我的 table 是否为空,如果没有发出更新请求,但是我的 recyclerview 无法正常工作,数据也没有在数据库上正确更新。这是我的代码:
private void getData() {
progressBar.setVisibility(View.VISIBLE);
APIInterface service = RetrofitInstance.getRetrofitInstance().create(APIInterface.class);
Call<DataAll> call = service.getData();
call.enqueue(new Callback<DataAll>() {
@Override
public void onResponse(Call<DataAll> call, Response<DataAll> response) {
if(response.body() != null) {
List<Data> allData = response.body().getData();
Disposable disposable = db.dataDao().dataSize().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer dbSize) throws Exception {
if(dbSize > 0)
updateData(allData);
else
insertData(allData);
fillListFromDb();
}
});
}
}
@Override
public void onFailure(Call<DataAll> call, Throwable t) {
tvErrorMessage.setVisibility(View.VISIBLE);
recyclerDataList.setVisibility(View.GONE);
progressBar.setVisibility(View.GONE);
swipeRefreshToUpdateList.setRefreshing(false);
Toast.makeText(getApplicationContext(), R.string.errorMessage, Toast.LENGTH_LONG).show();
t.printStackTrace();
}
});
}
private void fillListFromDb() {
Disposable disposable = db.dataDao().getAllData().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<List<Data>>() {
@Override
public void accept(List<Data> data) throws Exception {
listData.clear();
listData.addAll(data);
adapter = new MyAdapter(listData);
adapter.notifyDataSetChanged();
recyclerDataList.setAdapter(adapter);
progressBar.setVisibility(View.GONE);
swipeRefreshToUpdateList.setRefreshing(false);
}
});
}
private void updateData(List<Data> data) {
Completable.fromAction( () ->
db.dataDao().updateData(data))
.subscribeOn(Schedulers.io())
.subscribe();
}
private void insertData(List<Data> data) {
Completable.fromAction(() ->
db.dataDao().addData(data)).
subscribeOn(Schedulers.io())
.subscribe();
}
和onCreate方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
// ……
swipeRefreshToUpdateList.setOnRefreshListener(() -> {
tvErrorMessage.setVisibility(View.GONE);
recyclerDataList.setVisibility(View.VISIBLE);
getData();
});
}
请帮帮我
你必须在你的updateData
中一一检查你List<Data>
例如:
@Override
public void onResponse(Call<DataAll> call, Response<DataAll> response) {
if(response.body() != null) {
List<Data> allData = response.body().getData();
for (Data data:allData){
if(isStored(data.getId())){
updateData(data);
else {
insertData(data);
}
}
}
}
}
}
您可以在 DataDao
findDataById(string id)
中创建一个新方法并将其用于 boolean isStored(String id)
方法并直接更新它
祝你好运!希望对你有所帮助。
如果您希望insert
操作覆盖数据库中的现有对象,那么您应该使用OnConflictStrategy.REPLACE
。
参见示例:
@Dao
interface CatDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertCats(cats: List<Cat>)
我需要在刷新页面时向 API
发出请求并将获取数据插入我的房间数据库。但是当我尝试插入数据时,我得到 io.reactivex.exceptions.OnErrorNotImplementedException: UNIQUE constraint failed: data.id (code 1555).
所以我决定检查我的 table 是否为空,如果没有发出更新请求,但是我的 recyclerview 无法正常工作,数据也没有在数据库上正确更新。这是我的代码:
private void getData() {
progressBar.setVisibility(View.VISIBLE);
APIInterface service = RetrofitInstance.getRetrofitInstance().create(APIInterface.class);
Call<DataAll> call = service.getData();
call.enqueue(new Callback<DataAll>() {
@Override
public void onResponse(Call<DataAll> call, Response<DataAll> response) {
if(response.body() != null) {
List<Data> allData = response.body().getData();
Disposable disposable = db.dataDao().dataSize().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer dbSize) throws Exception {
if(dbSize > 0)
updateData(allData);
else
insertData(allData);
fillListFromDb();
}
});
}
}
@Override
public void onFailure(Call<DataAll> call, Throwable t) {
tvErrorMessage.setVisibility(View.VISIBLE);
recyclerDataList.setVisibility(View.GONE);
progressBar.setVisibility(View.GONE);
swipeRefreshToUpdateList.setRefreshing(false);
Toast.makeText(getApplicationContext(), R.string.errorMessage, Toast.LENGTH_LONG).show();
t.printStackTrace();
}
});
}
private void fillListFromDb() {
Disposable disposable = db.dataDao().getAllData().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<List<Data>>() {
@Override
public void accept(List<Data> data) throws Exception {
listData.clear();
listData.addAll(data);
adapter = new MyAdapter(listData);
adapter.notifyDataSetChanged();
recyclerDataList.setAdapter(adapter);
progressBar.setVisibility(View.GONE);
swipeRefreshToUpdateList.setRefreshing(false);
}
});
}
private void updateData(List<Data> data) {
Completable.fromAction( () ->
db.dataDao().updateData(data))
.subscribeOn(Schedulers.io())
.subscribe();
}
private void insertData(List<Data> data) {
Completable.fromAction(() ->
db.dataDao().addData(data)).
subscribeOn(Schedulers.io())
.subscribe();
}
和onCreate方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
// ……
swipeRefreshToUpdateList.setOnRefreshListener(() -> {
tvErrorMessage.setVisibility(View.GONE);
recyclerDataList.setVisibility(View.VISIBLE);
getData();
});
}
请帮帮我
你必须在你的updateData
中一一检查你List<Data>
例如:
@Override
public void onResponse(Call<DataAll> call, Response<DataAll> response) {
if(response.body() != null) {
List<Data> allData = response.body().getData();
for (Data data:allData){
if(isStored(data.getId())){
updateData(data);
else {
insertData(data);
}
}
}
}
}
}
您可以在 DataDao
findDataById(string id)
中创建一个新方法并将其用于 boolean isStored(String id)
方法并直接更新它
祝你好运!希望对你有所帮助。
如果您希望insert
操作覆盖数据库中的现有对象,那么您应该使用OnConflictStrategy.REPLACE
。
参见示例:
@Dao
interface CatDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertCats(cats: List<Cat>)