java - 使用 ViewModel 时如何获取插入实体的 id?
问题描述
根本问题:我想在 [Entity B] 的外键中设置 [Entity A] 的 id,但 [Entity A] 的 id 在插入数据库之前不可用(因为它是由 DBMS 自动生成的)。
使用架构组件(Room、ViewModel 和 LiveData),我如何执行在数据库中保存多个相关实体的事务?以下代码当前驻留在 ViewModel 中并且工作正常。问题是我想把它AsyncTask
像其他简单的单操作查询一样放在存储库层,但是可以吗?因为在这种情况下,存储库将负责管理关系并了解实体详细信息。
正如我上面所说,主要问题是我需要插入实体的 id 以便我可以将其保存在另一个实体中。如果不存在此要求,我将能够将每个实体一个一个地保存在AsyncTask
存储库中的单独 s 中。
MainViewModel.java:
public void buy(Item item, Store store) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
long storeId = mRepository.insertStore(store);
Purchase purchase = new Purchase(storeId); // here uses id of the store
long purchaseId = mRepository.insertPurchase(purchase);
item.setPurchaseId(purchaseId); // here uses id of the purchase
mRepository.updateItem(item);
return null;
}
}.execute();
}
解决方案
我认为如果您将其保留在存储库层中,那么您正在做的事情很好。我不认为将它保存在 ViewModel 中是一个好主意,因为它被认为是存储库的责任来处理您的数据,在这种情况下,Item
和Store
对象。我相信您的存储库应该负责管理这些数据及其关系。要回答有关接收更新实体 ID 的问题,您可以做的是让 AsyncTask 实现该onPostExecute
方法并让您的doInBackground
方法返回一个实际值(如storeId
)而不是null
. 然后,您可以onPostExecute
检索该值并将控制委托给某种回调侦听器。
推荐阅读
- amazon-web-services - AWS CloudFormation 创建 RDS 集群并将其 ARN 添加到同一模板中的策略
- google-drive-api - 无法更新或删除共享云端硬盘项目的继承权限
- flutter - 如何应用 BackdropFilter 模糊除中心以外的整个背景?
- swift - 有必要使用这个功能来播放声音吗?
- javascript - 如何轻松将 OpenCV.js 导入 .js 文件?
- javascript - 在 cloudfunction 中运行的 ffmpeg 静默失败/永远不会完成
- font-awesome - 字体真棒图标在移动设备上表现得像薛定谔的猫
- javascript - JavaScript 仅使用脚本标记发送自定义标头
- shell - Shell Scripting:“grep -w”不选择以“-”分隔的单词
- android - 如何使用 AndroidX 在 RecyclerView 中使用插入分隔符?