SQLDelight 关系
Posted
技术标签:
【中文标题】SQLDelight 关系【英文标题】:SQLDelight Relationships 【发布时间】:2021-10-08 10:29:35 【问题描述】:我想用SQLDelight 建模关系,尤其是一对多关系。
我有 2 张桌子:recipe
和 ingredient
。为简单起见,它们看起来像这样:
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
注释的东西。
【问题讨论】:
【参考方案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 映射到 ListRecipe
或按原样使用。以上是关于SQLDelight 关系的主要内容,如果未能解决你的问题,请参考以下文章