房间内多对多关系CRUD

时间:2020-09-25 01:16:07

标签: android android-room

我已经基于文档和此medium article与Room建立了多对多关系模型。使用此@Relation,我可以从数据库中检索RecipeWithIngredients或IngredientsWithRecipe对象。为此,我需要在配方表中插入一个配方,在配料表中插入一个配料,然后将两个ID都先插入到参考表中。我认为除了在Dao上使用@Transaction之外,没有其他方法可以完成插入操作,而只是在一个方法上完成所有操作,但是对于删除和更新,我是否也应该能够使用Relation处理这些操作? Room上的文档对我来说似乎有点缺乏,所以我来找你

enter image description here

//Get for recipeWithIngredients object. (This works)
@Transaction
@Query("SELECT * FROM Recipe WHERE recipeID = :ID")
suspend fun getRecipeWithIngredients(ID:Long): RecipeWithIngredients

//Insert recipeWithIngredients object. (I don't see why this wouldn't work)
//IDs are autoGenerated so I can't get them until they are inserted

@Transaction 
suspend fun insertRecipeWithIngredients(recipeWithIngredients: RecipeWithIngredients){
    val recipeID = insertRecipe(recipeWithIngredients.recipe)

    for(ingredient in recipeWithIngredients.ingredients){
        val ingredientID = insertIngredient(ingredient)
        insertRecipeIngredientRef(recipeID, ingredientID )

    }
}

//I could try doing this like the insert but should't there be a way to do it like the get?
@Transaction
@Query("SOME SQL HERE")
suspend fun deleteRecipeWithIngredients(recipeWithIngredients: RecipeWithIngredients)

1 个答案:

答案 0 :(得分:1)

除了在Dao上使用@Transaction并仅使用一种方法完成所有操作外,我认为没有其他方法可以插入

您用insertRecipeWithIngredients实现的想法很有趣,我想它应该可行,但是我不会说这是实现此目的的常用方法。通常,多对多关系是指您有两个单独的实体,即使它们之间没有关系也具有值(例如UserUserGroup)。即使在您的用例中,也可能是一个用户首先添加带有简短文本描述和所需步骤的食谱,然后另一个用户将其绑定了配料,因此insertRecipeinsertRecipeIngredients应该分开进行。 在此架构中,您应该实现三个单独的insert方法-第一个用于Recipe,第二个用于Ingridient,第三个-用于RecipeIngridientRef。但是,当然,在您的特定情况下,您可以像上面描述的那样进行操作。

对于删除和更新,我也不能使用“关系”来完成

开箱即用的Room不支持该功能。它仅用于查询。

如果要删除,请从RecipeIngridientRef中删除引用到特定配方的行,那么使用Foreign Key标准机制-级联删除就足够了。这样,您只需为食谱实体写delete,余下的Room&Sqlite会为您完成。

关于更新,文档中确实缺乏建议。选择之一-首先删除具有特定配方的RecipeIngridientRef中的所有行,然后对RecipeIngridientRef使用相同的方法插入(事务中的两个操作)。