多对多查询 查找所有含有 XX 成分的“食谱”
Posted
技术标签:
【中文标题】多对多查询 查找所有含有 XX 成分的“食谱”【英文标题】:Many to Many query Find all "recipes" with XX ingredients 【发布时间】:2014-05-22 12:41:49 【问题描述】:我正在做一个学校项目,所以我真的不是高级程序员,需要一些帮助来完成我需要进行的查询。
我的数据库结构如下所示。
配方表:
ID BIGINT 19
DESCRIPTION CLOB 2147483647
NAME VARCHAR 255
INGREDIENT 表:
ID BIGINT 19
NAME VARCHAR 255
RECIPE_INGREDIENT 表:
RECIPE_ID BIGINT 19
INGREDIENTS_ID BIGINT 19
这是我的模型类食谱
@Entity
public class Recipe extends Model
@ManyToMany(cascade=CascadeType.ALL)
public List<Ingredient> ingredients;
@Required
@Unique
public String name;
@Lob
@Required
public String description;
这是我的模型类成分
@Entity
public class Ingredient extends Model
@Required
@Unique
public String name;
我想做的查询是……我有一个用逗号分隔的字符串,例如milk,flour,egg
。使用该字符串,我想获取所有具有确切这些成分的食谱,假设一个食谱只有 flour
作为成分,那么这是真的。还有一个包含所有提到的等的食谱。
我已经修改了我昨天找到的一个查询字符串(不记得在哪里),但我无法让它工作。
我收到此错误:
IllegalArgumentException occured : org.hibernate.hql.ast.QuerySyntaxException: unexpected token: on near line 1, column 68 [select Recipe.name from models.Recipe inner join Recipe_Ingredient on Recipe.ID = Recipe_Ingredient.Recipe_ID inner join Ingredient on Recipe_Ingredient.Ingredient_ID = Ingredient.ID where Ingredient.name in ( 'milk') group by Recipe.name having count(*) = 2]
任何帮助将不胜感激!很抱歉,如果我在这篇文章中犯了任何错误。这是我第一次来这里:)
编辑:
查询现在看起来像这样:
Query query = JPA.em().createQuery("SELECT Recipe.name "
+ "FROM Recipe INNER JOIN "
+ "Recipe_Ingredient ON Recipe.ID = Recipe_Ingredient.Recipe_ID "
+ "INNER JOIN Ingredient "
+ "ON Recipe_Ingredient.Ingredient_ID = Ingredient.ID "
+ "WHERE Ingredient.name "
+ "IN ("+ingredientsCSV+") "
+ "GROUP BY Recipe.name HAVING count(*) = 2");
【问题讨论】:
您的查询还是不正确,因为您只是在开头和结尾添加了引号,因此寻找的成分'牛奶,面粉,鸡蛋',可能不存在。但是,第 1 行第 61 列指向 RECIPE_INGREDIENT 的连接,这很奇怪。你用的是什么 dbms? 谢谢,不知道我在想什么,我只用一种成分进行调试,所以我没有看到我犯的错误。我正在使用 H2 关系数据库 对不起,我不知道是什么导致了错误。该查询在我看来在语法上很好,我看不到任何违反 H2 选择语法的内容。 好的,很高兴知道这一点。谢谢,我会继续试错的方式 【参考方案1】:我认为你不能通过简单的查询来做到这一点。
为什么:
- 您需要知道所有成分是否都在您的成分字符串中。
使用having
并不能解决问题,因为不同的食谱会有不同的成分。
我不太熟悉 JPA 的工作原理,但在纯 sql(例如 mysql)中,您可以使用 view
来组织数据,然后再使用新查询处理数据。
很抱歉,我无法帮助您在 JPA 中进行该查询。
【讨论】:
【参考方案2】:看起来您需要以下引号:
... ('milk', 'flour', 'egg') 中的 Ingredient.name 按...分组。
【讨论】:
谢谢,确实如此!不过仍然会抛出同样的错误,所以我想我在该查询中犯了更多错误 现在有什么消息? 看起来您需要删除“模型”。就在 FROM 之后。 SELECT Recipe.name FROM Recipe INNER JOIN Recipe_Ingredient ON Recipe.ID = Recipe_Ingredient.Recipe_ID INNER JOIN Ingredient ON Recipe_Ingredient.Ingredient_ID = Ingredient.ID WHERE Ingredient.name IN ('milk') GROUP BY Recipe.name HAVING count(*) = 2 注意错误信息上的SQL,它有models.Recipe。 我不明白为什么它会被“添加”到配方中。那么为什么不使用成分呢?现在更新查询@问题以上是关于多对多查询 查找所有含有 XX 成分的“食谱”的主要内容,如果未能解决你的问题,请参考以下文章
RESTful API 设计更新 1/多对多关系的最佳实践?