当前位置: 首页 > 知识库问答 >
问题:

如何在使用LiveData时从房间检索自动生成的ID?

宿丰
2023-03-14

我正在创建一个Android应用程序,它将存储价值列表,例如。特定用户定义名称下不同时间的温度值。我打算使用SQLite来存储值,我读到使用Room将为它提供一个ORM层,所以我使用了它。但是后来我遇到了一个异常,基本上说我不能从主线程打开数据库连接,所以我尝试使用LiveData进行插入和检索。现在我有两张桌子。我只是想展示它们的结构,而不是在句法上准确:

**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表中插入值呢?web上的所有教程都给出了手动给定id的示例。

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

共有1个答案

芮宇航
2023-03-14

我认为可以通过在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
}
 类似资料:
  • 我遇到了一个问题,我找不到任何关于Android空间和自动生成主键的文档。 我有一个实体类,看起来有点像这样: 当我手动设置id时,这是正常的,但是当我不设置主键时,我得到一个关于主键为空的错误。看着自动生成的文件,我看不到它会自动增加主键的任何地方。 所以我想我的问题是:你能用setter自动生成私有成员的主键吗,或者我需要在setter中手动自动生成我的键吗?

  • 我如何从房间DAO改变我的LiveData的ViewModel源代码。在WordDao中,我有两个查询: 我还有存储库类: 和我的ViewModel类: 在我的活动中,我添加了观察者: LiveData的viewModel类源如何根据“isSortAsc”参数变化(words=isSortAsc?wordrepository.getwordsbyasc():wordrepository.getwo

  • 问题内容: 我正在尝试实现的是生成一个UUID,该UUID在数据库插入期间会自动分配。与名为“ id”的主键列相似,生成一个id值。 模型值看起来像这样: 但是当数据库插入完成时。“ uuid”为空。 非常感谢您的帮助。如果我问一个明显的愚蠢问题,对不起。 问题答案: 您可以使用诸如@PrePersist之类的事件来填充UUID字段 https://docs.jboss.org/hibernate

  • 我使用JSOUP获取网站。以下是网页链接: http://www.yelp.com/search?find_desc=restaurants&find_loc=Westmont%2C+il&ns=1&ls=43131f934bb3adf3#find_loc=hinsdale,+il&l=p:il:hinsdale::&sortby=rating&unfold=1 不幸的是,浏览器中的“view s