【发布时间】:2021-11-25 11:48:51
【问题描述】:
这个问题在某种程度上与my last question有关,因为它是同一个项目,但现在我正努力向前迈出一步。
所以,在我之前的问题中,我只有一张桌子;这次我有两个表:新的第二个表应该包含第一个表的行的相关属性,在 OneToMany 关系中。因此,我在第二个表中存储了一个 ForeignKey,它将存储第一个表的相关行的 Row ID(显然)。
问题是这样的:目的是同时创建两个寄存器(父和子),使用相同的形式,而 ParentTable 使用 AUTO_INCREMENT 作为他的 PrimaryKey(AKA ID)。 p>
由于 RoomDb 的工作方式,我使用 POJO 进行创建:但在插入后,据我所知,此 POJO 不会给我自动生成的 ID...所以,我能做到的唯一解决方法想象一下,在提交表单时,首先为父级创建 INSERT,然后使用创建父级的表单字段之一进行某种“SELECT * FROM parent_table WHERE field1 LIKE :field1”,检索 ID,然后使用该 ID 创建子表的 POJO 并执行下一个 INSERT 操作。但是我觉得这种方法有些不对劲,上次我以这种方式实现类似的东西时,我最终得到了很多自定义侦听器和回调地狱(我仍然对此做噩梦)。
关于自定义侦听器这件事,这是我最终为不同项目选择的不同问题的解决方案(有关此问题的更多详细信息,请参见old question)。看看那个老问题可能有助于添加一些关于我在 MVVM 架构中被误导的背景。但是,请注意当前的问题与 WebServices 无关,因为数据库纯粹是手机应用程序中的本地,没有外部来源。
但是,我想知道:这不是矫枉过正吗(我的意思是INSERT parent -> SELECT parentID -> INSERT child 的东西)?这样做是不可避免的,还是有更干净的方法?
我的 Repository 类中的“创建方法”如下所示:
public void insertParent(Parent parent) {
new InsertParentAsyncTask(parent_dao).execute(parent);
}
private static class InsertParentAsyncTask extends AsyncTask<Parent, Void, Void> {
private final ParentDao parent_dao;
private InsertParentAsyncTask(ParentDao parent_dao) {
this.parent_dao = parent_dao;
}
@Override
protected Void doInBackground(Parent... parents) {
parent_dao.insert(parents[0]);
return null;
}
}
试图按照马里奥的回答,我在我父母的 DAO 中改变了这个方法:
// OLD
@Insert
void insert(Parent parent);
// NEW (yes, I use short type for parent's ID)
@Insert
short insert(Parent parent);
EDIT2: 现在,我正在尝试对我的存储库的插入 AsyncTask 进行更改,如下所示:
private static class InsertParentAsyncTask extends AsyncTask<Parent, Void, Short> {
private final ParentDao parent_dao;
private InsertParentAsyncTask(ParentDao parent_dao) {
this.parent_dao = parent_dao;
}
@Override
protected Short doInBackground(Parent... parents) {
short parent_id;
parent_id = parent_dao.insert(parents[0]);
return parent_id;
}
@Override
protected void onPostExecute(Short hanzi_id) {
// TODO ??? What now?
}
}
长话短说
它在这里对我有用,但这不是干净的代码(显然):
// TODO I am aware that AsyncTask is deprecated
// My Repository class uses this
public void insertParentAndChildren(Parent parent, String[] children_list) {
new InsertParentAndChildrenAsyncTask(parent_dao, children_list).execute(parent);
}
private static class InsertParentAndChildrenAsyncTask extends AsyncTask<Parent, Void, Short> {
private final ParentDao parent_dao;
private String[] children_list;
private InsertParentAndChildrenAsyncTask(ParentDao parent_dao, String[] children_list) {
this.parent_dao = parent_dao;
this.children_list = children_list;
}
@Override
protected Short doInBackground(Parent... parents) {
short parent_id;
Long row_id = parent_dao.insert(parents[0]);
parent_id = parent_dao.getIdForRowId(row_id);
return parent_id;
}
@Override
protected void onPostExecute(Short parent_id) {
// Second "create method" for children
for (int n = 0; n < children_list.length; n++) {
Child child = new Child();
child.setParentId( parent_id );
child.setMeaning( children_list[n] );
// My Repository has this method as well
insertChildStaticMethod(child);
}
}
}
【问题讨论】:
标签: java android relational-database android-room auto-increment