android - relaciones - fondos de pantalla en movimiento the walking dead
Sala Android: ¿Cómo modelar las relaciones? (2)
Acabo de comenzar a trabajar con Room y, aunque todo parece ser bastante intuitivo, actualmente no entiendo exactamente cómo podría manejar las relaciones.
Debido a que SQLite es una base de datos relacional, puede especificar relaciones entre objetos. Aunque la mayoría de las bibliotecas ORM permiten que los objetos de entidad se hagan referencia entre sí, Room lo prohíbe explícitamente. Aunque no puede usar relaciones directas, Room aún le permite definir restricciones de clave externa entre entidades. (Fuente: https://developer.android.com/topic/libraries/architecture/room.html#no-object-references )
- ¿Cómo se debe modelar una relación de muchos a muchos o de uno a muchos ?
- ¿Cómo sería esto en la práctica (ejemplo DAOs + Entidades)?
Creé un método de conveniencia simple que rellena manualmente una relación de uno a muchos. Por ejemplo, si tiene uno a muchos entre País y Ciudad, puede usar el método para poblar manualmente la propiedad cityList en País.
/**
* @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 <T1> Table One Type
* @param <T2> Table Two Type
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws NoSuchMethodException
* @throws InvocationTargetException
*/
private static <T1, T2> void oneToMany(List<T1> tableOne, List<T2> 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<T2> 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);
}
}
Así es como lo uso.
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;
});
Puede usar la anotación @Relation
para manejar las relaciones en la sala.
Una anotación de conveniencia que se puede utilizar en un Pojo para buscar automáticamente entidades de relación. Cuando el Pojo se devuelve de una consulta, todas sus relaciones también son recuperadas por Room.
(El documento de Google tiene ejemplos confusos. He escrito los pasos y algunas explicaciones básicas en mi otra respuesta. Puede verificarlo )