在创建某些服务时,我遇到了一些性能问题,例如: 调用服务并获得响应(对于一个包含RecipeComponents列表的对象Recipe - 花了近2000ms),看起来像这样:
val mEndpointDiscoveryCallback = object : EndpointDiscoveryCallback() {
// We found someone to connect to!
override fun onEndpointFound(endpointId: String, info: DiscoveredEndpointInfo) {
Log.d(TAG, "onEndpointFound (we want to connect to someone!) (endpointId=$endpointId, serviceId=${info.serviceId}, endpointName=${info.endpointName})")
if (SERVICE_ID == info.serviceId) {
Nearby.Connections.acceptConnection(mGoogleApiClient, endpointId, mPayloadCallback)
.setResultCallback { status ->
if (!status.isSuccess) {
Log.w(TAG, "acceptConnection failed with ${status.toReadable()}")
} else {
Log.d(TAG, "acceptConnection success")
endpoints.add(endpointId)
}
}
} else {
Log.w(TAG, "onEndpointFound ignoring unknown endpointId=$endpointId serviceId=${info.serviceId}")
}
}
70多个配方(含有组件)获得响应需要大约10000毫秒
原因是服务方法,实际上调用数据库2次(在开始时我没有意识到它很慢):
{
"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
}
]
}
在存储库层中我有两个类:RecipeRowMapper和RecipeComponentRowMapper来映射数据 - 如上所示,它适用于单个查询。
所以我决定在存储库层中使用ResultSetExtractor,其中将使用left join / inner join语句进行单个查询。
@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;
并且在这种情况下我得到响应(对于70个食谱)大约1000毫秒,但问题是响应不完整(没有完整的recipeComponents列表,但只有列表中的第一个组件):
@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;
}
**我的查询工作正常。
[
{
"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
}
]
}
]
我也在这里找到一些想法切换到ORM来解决这个问题,但如果你有一些想法,其他解决这个问题的解决方案我将不胜感激。
答案 0 :(得分:0)
好吧,我解决了这个问题,这里应该如何编写:
@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;
}
我希望有一天这会帮助某人:)