2017-09-25 6 views
0

サービスを作成する際に、パフォーマンスの問題が発生しました。例えば、 サービスを呼び出して応答を取得する(RecipeComponents - it実際に(2回データベースを呼び出し、それが理由はserviceメソッドで周りを含むオブジェクトいくつかのアイテムのリストは単一のクエリで休憩データを表示できません

を10000msかかる応答を取得するためのコンポーネントと70+レシピ()のための

{ 
    "recipe_id": 55, 
    "recipeName": "Pizza", 
    "weight": 450, 
    "aproxPrice": 12, 
    "raiting": 7, 
    "caloriesCat": 1, 
    "foodCat": 2, 
    "calories": 300, 
    "user_id": 500, 
    "publishDate": 1505858400000, 
    "recipeComponents": [ 
     { 
      "component_id": 139, 
      "componentName": "veges", 
      "componentWeight": 100, 
      "componentDescription": "Some desc", 
      "componentCalories": 200 
     }, 
     { 
      "component_id": 140, 
      "componentName": "rice", 
      "componentWeight": 100, 
      "componentDescription": "some stuff", 
      "componentCalories": 350 
     }, 
     { 
      "component_id": 141, 
      "componentName": "tomato", 
      "componentWeight": 100, 
      "componentDescription": "XXXXXXX", 
      "componentCalories": 150 
     }, 
     { 
      "component_id": 142, 
      "componentName": "souce", 
      "componentWeight": 100, 
      "componentDescription": "xxsdsds", 
      "componentCalories": 250 
     } 
    ] 
} 

:このどのように見えるか、)はほぼ2000ミリ秒を要しました私はそれがかなり遅いことを実感しませんでした):

@Override 
public List<Recipe> getAllRecipes() { 
    List<Recipe> recipes = recipeRepository.getAllRecipes(); <- first time to get all recipes 
    for (Recipe recipe : recipes) { 
     List<RecipeComponent> components = recipeComponentRepository 
       .findAllComponentsAssignedToRecipe(recipe.getRecipe_id()); <- 2nd time to get components assigned to recipe. 
     recipe.setRecipeComponents(components); 
    } 
    return recipes; 

レポジトリ層には2つのクラスがあります:RecipeRowMapperとRecipeComponentRowMapperを使用してデータをマップします。これは上記のように1つのクエリでうまく機能します。

私はリポジトリ層でResultSetExtractorを使用することに決めました。ここでは左結合/内部結合文を使用した単一クエリが使用されます。

@Override 
public List<Recipe> getAllRecipesWithSingleQuery() { 

    List<Recipe> recipes = jdbcTemplate.query(SqlRecipeStaticData.sGetAllRecipesWithSingleQuery, 
      new ResultSetExtractor<List<Recipe>>() { 

       public RecipeComponentRowMapper componentRowMapper = new RecipeComponentRowMapper(); 

       public RecipeRowMapper recipeRowMapper = new RecipeRowMapper(); 

       @Override 
       public List<Recipe> extractData(ResultSet rs) throws SQLException, DataAccessException { 
        List<Recipe> recipes = new ArrayList<>(); 
        Integer recipeId = null; 
        Recipe currentRecipe = null; 
        int recipeIdx = 0; 
        int componentIdx = 0; 
        while (rs.next()) { 
         if (currentRecipe == null || !recipeId.equals(rs.getInt("recipe_id"))) { 
          recipeId = rs.getInt("recipe_id"); 
          currentRecipe = new Recipe(); 

          currentRecipe = recipeRowMapper.mapRow(rs, recipeIdx++); 
          List<RecipeComponent> components = currentRecipe.getRecipeComponents(); 
          if (components == null) { 
           components = new ArrayList<>(); 

           RecipeComponent component = componentRowMapper.mapRow(rs, componentIdx++); 

           components.add(component); 

          } 

          currentRecipe.setRecipeComponents(components); 
          recipes.add(currentRecipe); 

         } 

        } 
        return recipes; 
       } 

      }); 
    return recipes; 
} 

この場合には、私が1000ミリ秒の周りの何かに(70本のレシピのための)応答を得るが、問題は(doesntのはrecipeComponentsの完全なリストを持っているが、リストの最初のコンポーネント)の応答が完了していないです。

[ 
    { 
     "recipe_id":55, 
     "recipeName":"Pizza", 
     "weight":450, 
     "aproxPrice":12, 
     "raiting":7, 
     "caloriesCat":1, 
     "foodCat":2, 
     "calories":300, 
     "user_id":500, 
     "publishDate":1505858400000, 
     "recipeComponents":[ 
     { 
      "component_id":139, 
      "componentName":"veges", 
      "componentWeight":100, 
      "componentDescription":"Some desc", 
      "componentCalories":200 
     } 
     ] 
    } 
] 

**私のクエリは正常に動作します。

select recipe_id,recipe_name,recipe_weight,recipe_aprox_price,recipe_raiting,recipe_calories,recipe_user_id,recipe_kcategory_id,recipe_fcategory_id,recipe_published_date,comp_id, comp_name,comp_weight,comp_description,comp_calories,comp_recipe_id from public.recipe_store INNER JOIN public.recipe_components ON (public.recipe_store.recipe_id=public.recipe_components.comp_recipe_id) 

私はこの問題を解決するためにORMに切り替えるためにここにもいくつかのアイデアを見つけるが、あなたはいくつかのアイデアを持っている場合、このproblmsを解決するために、他のソリューションは、私は感謝するでしょう。

答えて

0

さてさて、私はこの問題を解決し、ここではそれが書かれるべきかasnwerです:

@Override 
    public List<Recipe> getAllRecipesWithSingleQuery() { 
     final Map<Integer,Recipe> recipesAll = new HashMap<>(); 
     this.jdbcTemplate.query(SqlRecipeStaticData.sGetAllRecipesWithSingleQuery, new RowMapper<RecipeComponent>(){ 

      @Override 
      public RecipeComponent mapRow(ResultSet rs, int rowNum) throws SQLException { 
       Integer recipeId = rs.getInt("r_id"); 
       Recipe recipe = recipesAll.get(recipeId); 
       if(recipe==null){ 
        recipe = new Recipe(); 
        recipe.setRecipe_id(recipeId); 
        recipe.setRecipeName(rs.getString("recipe_name")); 
        recipe.setAproxPrice(rs.getDouble("recipe_aprox_price")); 
        recipe.setWeight(rs.getDouble("recipe_weight")); 
        recipe.setRaiting(rs.getInt("recipe_raiting")); 
        recipe.setCalories(rs.getDouble("recipe_calories")); 
        recipe.setUser_id(rs.getInt("ruser_id")); 
        recipe.setCaloriesCat(rs.getInt("kcategory_id")); 
        recipe.setFoodCat(rs.getInt("fcategory_id")); 
        recipe.setPublishDate(rs.getDate("published_date")); 
        recipe.setRecipeComponents(new ArrayList<>()); 
        recipesAll.put(recipeId, recipe); 
       } 
       RecipeComponent component = new RecipeComponent(); 
       component.setComponent_id(rs.getInt("id")); 
       component.setComponentName(rs.getString("name")); 
       component.setComponentWeight(rs.getDouble("weight")); 
       component.setComponentDescription(rs.getString("description")); 
       component.setRecipe_id(recipeId); 
       component.setComponentCalories(rs.getDouble("calories")); 
       recipe.getRecipeComponents().add(component); 

       return component; 

      } 


     }); 
     List<Recipe> result = new ArrayList<Recipe>(recipesAll.values()); 
     return result; 


    } 

私はいつの日か、これは誰か:)

を役に立てば幸い
関連する問題