Lors de la création de certains services, je rencontre des problèmes de performance, par exemple: pour appeler le service et obtenir une réponse (pour un objet Recette qui contient la liste des RecipeComponents - it a pris presque 2000ms), ce qui ressemble à ceci:objet qui contient la liste de certains éléments ne peut pas exposer les données de repos avec une seule requête
{
"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
}
]
}
pour plus de 70 recettes (avec des composants) pour obtenir la réponse qu'il faut 10000ms autour
la raison est la méthode de service, appelez en fait la base de données 2 fois (au débutant je n'ai pas réalisé son assez lent):
dans le niveau de dépôt j'ai deux classes: RecipeRowMapper et RecipeComponentRowMapper pour mapper des données qui fonctionne bien pour les requêtes simples comme vous pouvez le voir ci-dessus. J'ai donc décidé d'utiliser ResultSetExtractor dans le niveau du référentiel, où sera une requête unique avec une jointure à gauche/une jointure interne.
@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;
}
et dans ce cas j'obtenir une réponse (pour 70 recettes) dans quelque chose autour de 1000ms, mais le problème est la réponse est incomplète (ne marche pas avoir la liste complète des recipeComponents, mais seulement le premier composant sur la liste):
[
{
"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
}
]
}
]
** ma requête fonctionne correctement.
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)
Je trouve aussi ici quelques idées pour passer à ORM pour résoudre ce problème, mais si vous avez des idées, d'autres solutions pour résoudre ce problms je serai reconnaissant.