【问题标题】:SQLDelight RelationshipsSQLDelight 关系
【发布时间】:2021-10-08 10:29:35
【问题描述】:

我想用SQLDelight 建模关系,尤其是一对多关系。

我有 2 张桌子:recipeingredient。为简单起见,它们看起来像这样:

CREATE TABLE recipe (
  id INTEGER NOT NULL PRIMARY KEY,
  name TEXT NOT NULL
)

CREATE TABLE ingredient (
  recipe_id INTEGER NOT NULL,
  name TEXT NOT NULL,
  FOREIGN KEY (recipe_id) REFERENCES recipe(id) ON DELETE CASCADE
);

所以我有一个食谱列表,每个食谱可以包含 0-n 种成分。

我有两个目标:

  • 编写包含所有成分的食谱
  • 阅读包含所有成分的食谱

我很确定第一个只能手动完成,例如插入配方,然后手动插入相关成分。

对于后者,我尝试使用以下语句加入表格:

selectWithIngredients:
SELECT *
FROM recipe
INNER JOIN ingredient ON recipe.id = ingredient.recipe_id
WHERE recipe.id=?;

SQLDelight 为我生成了一个 1:1 的关系文件:

public data class SelectWithIngredients(
  public val id: Long,
  public val name: String,
  public val recipe_id: Long,
  public val name_: String,
)

有没有什么好的方法可以用一个生成的函数来检索数据(配方 + 成分列表)?类似于 Rooms @Embedded@Relation 注释的东西。

【问题讨论】:

    标签: android kotlin relationship sqldelight


    【解决方案1】:

    不幸的是,SQLDelight 没有那么精致。它所做的只是为查询的每一行提供一个数据类,如果你想做更复杂的逻辑,比如将一个表映射到另一个表的列表,而不是你需要在 kotlin 中自己做。

    例如有这样的食谱

    data class Recipe(val name: String, val ingredients: List<String>)
    

    你可以用你的选择来做到这一点

    val rows: List<SelectWithIngredients> 
    
    rows.groupBy { it.name }
        .map { (recipe, selectRows) -> 
                Recipe(name, selectRows.map { it.name_ } 
        }  
    

    【讨论】:

    • 我同意! Kotlin 在这方面做得很好。
    • 如果我理解正确,这是否意味着我必须进行 2 次查询?当然 Kotlin 擅长这一点,但这很可能意味着性能比一个查询更差。
    • 不,您仍然可以使用您唯一的 SELECT 查询。它将返回 SQLDelight 映射到 List 的行列表。您将在每一行中都有一个食谱名称。因此,您只需将其转换为获取 Recipe 或按原样使用。
    • 啊,是的。这应该足够了。谢谢!
    猜你喜欢
    • 2022-10-23
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2021-06-22
    相关资源
    最近更新 更多