我正在创建一个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
最初,我想到不要强制外键关系,而只是像Hibernate那样插入PLACE_DETAILS对象,并在进一步插入TEMPERATURE_DETAILS表中使用它时,才检索生成的键。但是,从这个问题来看:
Room API - How to retrieve recently inserted generated id of the entity?
我发现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);
}
}
}
答案 0 :(得分:2)
我认为您可以通过在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
}