Java Play Framework使用Find和JPQL创建一个带有来自字符串列表的重复项的对象列表

时间:2012-03-17 12:20:42

标签: java playframework jpql

所以我是Java的新手,Play仍然不时地对准面向对象编程感到困惑......

我需要将带有重复值的分隔字符串转换为Object列表,也使用这些重复值,其顺序与字符串相同。

示例:

我有一个用户提交空格分隔字符串的表单。例如:

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;
}

我将String列表的循环打印到屏幕并获得预期的: 苹果 橙子 香蕉 苹果 葡萄 苹果

我在foodList的循环中打印每个的Food.name值并得到: 葡萄 苹果 香蕉 橙

这显然是WHERE子句中IN的问题,因为这是预期的行为。

所以,我目前的解决方案是通过循环遍历List并在List食物中的每个String上运行以下命令来手动填充List

List<Food> foodList = new ArrayList<Food>(foods.size());
    for ( String name: foods ){
        Food food = Food.find("byName", name).first();
        foodList.add(food);
    }

这是我想要的方式,但似乎并不优雅或高效。需要重复,所以我认为排除IN。有没有人有更好的想法?如果答案是否定的,也会很感激!

非常感谢。

1 个答案:

答案 0 :(得分:0)

没有(至少不合理)构建这样的JPQL查询的方法。如果在循环bothers中执行太多查询,您可以在一个查询中获取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;
}

此外,您必须决定是否缺少某些名称的食物会产生结果的空条目,或者在这种情况下您更喜欢异常。