Android会议室:如何建立关系模型?

我刚刚开始与Room合作,虽然一切看起来都非常直观,但我目前还不清楚我究竟能如何处理关系。

由于SQLite是关系数据库,因此您可以指定对象之间的关系。 尽管大多数ORM库允许实体对象相互引用,但Room明确禁止这样做。 即使您不能使用直接关系,Room仍然允许您在实体之间定义外键约束。(来源: https : //developer.android.com/topic/libraries/architecture/room.html#no-object-references )

  1. 你应该如何模拟多对多一对多的关系?
  2. 这在实践中会是什么样子(示例DAO +实体)?

您可以使用@Relation注释来处理Room的关系。

一个便利注释,可以在Pojo中用于自动获取关系实体。 当从查询返回Pojo时,它的所有关系也由Room提取。

见文件。

(谷歌的文件有令人困惑的例子。我已经在另一个答案中写了步骤和一些基本的解释。你可以看一下 )

我创建了一个简单的便捷方法,手动填充一对多的关系。 因此,例如,如果Country和City之间有一对多,则可以使用该方法手动填充Country中的cityList属性。

 /** * @param tableOne The table that contains the PK. We are not using annotations right now so the pk should be exposed via a getter getId(); * @param tableTwo The table that contains the FK. We are not using annotations right now so the Fk should be exposed via a getter get{TableOneName}Id(); eg. getCountryId(); * @param  Table One Type * @param  Table Two Type * @throws NoSuchFieldException * @throws IllegalAccessException * @throws NoSuchMethodException * @throws InvocationTargetException */ private static  void oneToMany(List tableOne, List tableTwo) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { String tableOneName = tableOne.get(0).getClass().getSimpleName(); String tableTwoName = tableTwo.get(0).getClass().getSimpleName(); for (T1 t1 : tableOne) { Method method = t1.getClass().getMethod("getId"); Integer pkId = (Integer) method.invoke(t1); List listForCurrentId = new ArrayList<>(); for (T2 t2 : tableTwo) { Method fkMethod = t2.getClass().getDeclaredMethod("get".concat(tableOneName).concat("Id")); Integer fkId = (Integer) fkMethod.invoke(t2); if (pkId == fkId) { listForCurrentId.add(t2); } } Method tableTwoList = t1.getClass().getMethod("set".concat(tableTwoName).concat("List"), List.class); tableTwoList.invoke(t1, listForCurrentId); } } 

这就是我使用它的方式。

  SystemDefaults systemDefaults = new SystemDefaults(); return Single.zip(systemDao.getRoles(), systemDao.getCountries(), systemDao.getCities(), (roles, countries, cities) -> { systemDefaults.setRoles(roles); *ConvenienceMethods.oneToMany(countries,cities);* systemDefaults.setCountries(countries); return systemDefaults; });