所以我是 Java 的新手,Play 仍然不时对准面向对象编程感到困惑......
我需要将包含重复值的分隔字符串转换为对象列表,也包含那些重复值,顺序与字符串相同。
例子:
我有一个表单,用户可以在其中提交以空格分隔的字符串。例如:
http://www.feedme.com?food=apple+orange+banana+apple+grape+apple
去
public static List<Food> getFoodList(String foodString) {
foodString = foodString.trim();
List<String> foods = Arrays.asList(foodString.split("\\s+"));
List<Food> foodList = Food.find("name IN (:foods)").bind("foods", foods).fetch();
return foodList;
}
我将字符串列表的循环打印到屏幕并得到预期的结果: 苹果 橙子 香蕉 苹果 葡萄 苹果
我在 foodList 的循环中打印每个的 Food.name 值并得到: 葡萄 苹果 香蕉 橙色
这显然是 WHERE 子句中 IN 的问题,因为这是预期的行为。
因此,我当前的解决方案是通过遍历 List 并在 List foods 中的每个字符串上运行以下命令来手动填充 List
List<Food> foodList = new ArrayList<Food>(foods.size());
for ( String name: foods ){
Food food = Food.find("byName", name).first();
foodList.add(food);
}
这按我想要的方式工作,但看起来不是很优雅或高效。重复项是必需的,所以我认为这排除了 IN。有没有人有更好的主意?如果答案是否定的,我也将不胜感激!
非常感谢。
最佳答案
没有(至少不合理)构造这样的 JPQL 查询的方法。如果在循环中执行太多查询很麻烦,您可以在一个查询中获取 Food 实体,然后用类似的东西映射它们(未编译/测试,但只是作为一个想法):
List<Food> matchFoodNamesToFoods(List<String> foodNames , List<Food> foodList ) {
final ArrayList<Food> result = new ArrayList<Food>();
for (String foodName: foodNames) {
for (Food food: foodList) {
if (food.getName().equals(foodName)) {
result.add(food);
}
//maybe you want to add null here when no match
}
}
return result;
}
根据 foodList 的大小和重复项的预期数量(也许您也发现它更清楚),您还可以首先使用 foodName/Food 条目创建 map 并在内部循环中查询它:
List<Food> matchFoodNamesToFoods(List<String> foodNames , List<Food> foodList ) {
final ArrayList<Food> result = new ArrayList<Food>();
final Map<String, Food> foodNameToFood = new HashMap<String, Food>();
for (Food food: foodList) {
for (String foodName: foodNames) {
if (food.getName().equals(foodName)) {
foodNameToFood.put(foodName, food);
}
}
}
for (String foodName: foodNames) {
result.add(foodNameToFood.get(foodName));
}
return result;
}
此外,您还必须确定缺少某个名称的 Food 是否会导致结果为空条目,或者是否属于异常现象,您宁愿在这种情况下通过异常(exception)处理。
关于Java Play Framework 使用 Find 和 JPQL 创建一个包含字符串列表中重复项的对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9749939/