[英]How to retrieve auto generated ID from Room when using LiveData?
我正在创建一个将存储值列表的Android应用程序,例如。 在特定的用户定义名称下,不同时间的温度值。 我打算使用SQLite来存储值,并且我读到使用Room将为其提供一个ORM层,因此我使用了它。 但是后来我遇到了一个异常,该异常基本上说我无法从主线程打开数据库连接,因此我尝试使用LiveData进行插入和检索。 现在我有2张桌子。 我只是试图显示它们的结构,而语法上并不准确:
**PLACE_DETAILS**
place_id integer auto_increment
place_name string
latitude double
longitude double
**TEMPERATURE_DETAILS**
temperature_id integer auto_increment
place_id foreign key references place_details(place_id)
time_of_record timestamp
temperature float
最初,我考虑过不强制外键关系,只是在插入PLACE_DETAILS对象时(如Hibernate所做的那样),并在进一步插入TEMPERATURE_DETAILS表中使用它时,才检索生成的键。 但是,从这个问题来看:
我发现DAO方法本身需要返回一个代表生成的ID的长值。
@Insert
long insertPlaceDetails(PlaceDetails placeDetails);
但是,在ViewModel中运行的AsyncTask需要重写以Void作为返回值的doInBackground()方法。
public class PlaceDetailsViewModel extends AndroidViewModel {
private final LiveData<List<PlaceDetails>> placeDetailsList;
private PlaceDatabase placeDatabase;
public PlaceDetailsViewModel(@NonNull Application application) {
super(application);
placeDatabase = PlaceDatabase.getDatabase(this.getApplication());
placeDetailsList = placeDatabase.daoAccess().fetchAllPlaceDetails();
}
public LiveData<List<PlaceDetails>> getPlaceDetailsList() {
return placeDetailsList;
}
public void addPlace(final PlaceDetails placeDetails) {
Log.d("Adding", "Place: " + placeDetails.getPlaceName());
new addAsyncTask(placeDatabase).execute(placeDetails);
}
private static class addAsyncTask extends AsyncTask<PlaceDetails, Void, Void> {
private PlaceDatabase placeDatabase;
addAsyncTask(PlaceDatabase placeDatabase) {
this.placeDatabase = placeDatabase;
}
@Override
protected Void doInBackground(PlaceDetails... placeDetails) {
placeDatabase.daoAccess().insertPlaceDetails(placeDetails[0]);
return null;
}
}
}
那么,实际上如何才能在代码中检索生成的ID? 另外,如果LiveData无法为我提供此值并且关系是解决方法,那么我又如何根据PLACE_DETAILS表中自动生成的外键在TEMPERATURE_DETAILS表中插入值? 网络上的所有教程都提供了示例,这些示例中已经手动给出了ID。
编辑
根据anhtuannd给出的建议,我修改了VieModel类。 但是,返回的值始终为-1。 这本身表明没有任何内容插入数据库。 我的清单中有WRITE_EXTERNAL_STORAGE权限。 要进行此操作,还需要其他任何方法吗?
public class PlaceDetailsViewModel extends AndroidViewModel {
private final LiveData<List<PlaceDetails>> placeDetailsList;
private PlaceDatabase placeDatabase;
private long insertId = -1;
public long getInsertId() {
return insertId;
}
public PlaceDetailsViewModel(@NonNull Application application) {
super(application);
placeDatabase = PlaceDatabase.getDatabase(this.getApplication());
placeDetailsList = placeDatabase.daoAccess().fetchAllPlaceDetails();
}
public LiveData<List<PlaceDetails>> getPlaceDetailsList() {
return placeDetailsList;
}
public void onPlaceInserted(long id) {
insertId = id;
}
public void addPlace(final PlaceDetails placeDetails) {
Log.d("Adding", "Place: " + placeDetails.getPlaceName());
new addAsyncTask(placeDatabase).execute(placeDetails);
}
private class addAsyncTask extends AsyncTask<PlaceDetails, Void, Void> {
private PlaceDatabase placeDatabase;
addAsyncTask(PlaceDatabase placeDatabase) {
this.placeDatabase = placeDatabase;
}
@Override
protected Void doInBackground(PlaceDetails... placeDetails) {
insertId = placeDatabase.daoAccess().insertPlaceDetails(placeDetails[0]);
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
onPlaceInserted(insertId);
}
}
}
我认为您可以通过在onPostExecute中使用回调函数来获取ID:
private static class addAsyncTask extends AsyncTask<PlaceDetails, Void, Void> {
private PlaceDatabase placeDatabase;
private PlaceDetails place;
private int insertId = -1;
addAsyncTask(PlaceDatabase placeDatabase) {
this.placeDatabase = placeDatabase;
}
@Override
protected Void doInBackground(PlaceDetails... placeDetails) {
place = placeDetails[0];
insertId = placeDatabase.daoAccess().insertPlaceDetails(place);
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
onPlaceInserted(insertId, place);
}
}
void onPlaceInserted(int id, PlaceDetails place) {
// you get ID here
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.