【发布时间】:2012-01-31 04:38:49
【问题描述】:
我正在尝试在服务器端使用 JSP 来执行可变数量的查询,并将所有查询的结果作为 ExtJS 折线图的单个 JSON 数据块输出。
查询数之所以可变,是因为每个查询在折线图上代表不同的系列(不同的线),而系列的数量根据用户选择的折线图而有所不同。
我正在使用休眠,我的持久性类将每个查询数据返回为:List<Map<String, Object>>(每个 Map 代表一行)。
总会有至少一个系列(图表上的一条线,一个要执行的查询),所以我想设置它的方式如下:
1) 运行初始查询并获取第一个系列
2) 运行另一个查询以检查应在图表上的任何其他系列
3) 对于在第二个查询中找到的每个“其他”系列,运行一个查询以获取该系列的数据(相同的行数),然后将该数据合并到 #1 中返回的第一个 List<Map<String, Object>> 中另一列。查询已设置为正确排序,只需在同一索引级别合并即可。
4) 将该列表输出为 JSON。
我的问题是#3,我不确定如何合并数据。
这是我目前所拥有的:
GenericSelectCommand graphData = new GenericSelectCommand(graphDataQuery);
GenericSelectCommand backSeriesData = new GenericSelectCommand(backSeriesQuery);
List<Map<String, Object>> graphDataList;
List<Map<String, Object>> backSeriesList;
try
{
Persistor myPersistor = new Persistor();
// 1) GET THE INITIAL LINE CHART SERIES
myPersistor.executeTransact(graphData);
graphDataList = graphData.getRows();
// 2) LOOK FOR ANY ADDITIONAL SERIES THAT SHOULD BE ON THE LINE CHART
myPersistor.executeTransact(backSeriesData);
backSeriesList = backSeriesData.getRows();
// 3) FOR EACH ADDITIONAL SERIES FOUND, RUN A QUERY AND APPEND THE DATA TO THE INITIAL LINE CHART SERIES (graphDataList)
for (int i = 0; i < backSeriesList.size(); i++)
{
Map<String, Object> backSeriesBean = backSeriesList.get(i);
// THIS QUERY RETURNS ONE COLUMN OF INT VALUES (THE LINE CHART DATA) WITH THE EXACT SAME NUMBER OF ROWS AS THE INITIAL LINE CHART SERIES (graphDataList)
String backDataQuery = "exec runQuery 'getBackData', '" + backSeriesBean.get("series_id") + "'";
GenericSelectCommand backData = new GenericSelectCommand(backDataQuery);
myPersistor.executeTransact(backData);
List<Map<String, Object>> backDataList = backData.getRows();
// FOR EACH RECORD IN THE BACK DATA (Map<String, Object>)
for (int i = 0; i < backDataList.size(); i++)
{
Map<String, Object> backDataBean = backDataList.get(i);
// HOW DO I ADD IT TO THE RECORD AT THE SAME INDEX LEVEL IN graphDataList (List<Map<String, Object>>)
}
}
}
catch (Throwable e)
{
System.err.println("Error: ");
System.err.println(e.getCause());
}
finally
{
myPersistor.closeSession();
}
// 4) RETURN THE DATA AS JSON NOW THAT IT IS MERGED
for (int i = 0; i < graphDataList.size(); i++)
{
Map<String, Object> graphDataBean = graphDataList.get(i);
out.println(/*JSON FORMAT + graphDataBean.get('data') + JSON FORMAT*/)
}
解决方案:
GenericSelectCommand graphData = new GenericSelectCommand(graphDataQuery);
GenericSelectCommand backSeries = new GenericSelectCommand(backSeriesQuery);
List<Map<String, Object>> graphDataList = Collections.emptyList();
List<Map<String, Object>> backSeriesList = Collections.emptyList();
List backDataListArray = new ArrayList();
try
{
// GET THE INITIAL LINE CHART SERIES
Persistor.instance().executeTransact(graphData);
graphDataList = graphData.getRows();
// LOOK FOR ANY ADDITIONAL SERIES THAT SHOULD BE ON THE LINE CHART
Persistor.instance().executeTransact(backSeries);
backSeriesList = backSeries.getRows();
// FOR EACH ADDITIONAL SERIES FOUND, RUN THE QUERY AND ADD IT TO backDataListArray
for (int i = 0; i < backSeriesList.size(); i++)
{
Map<String, Object> backSeriesBean = backSeriesList.get(i);
String backDataQuery = "exec runQuery 'getBackData', " + backSeriesBean.get("series_id");
GenericSelectCommand backData = new GenericSelectCommand(backDataQuery);
Persistor.instance().executeTransact(backData);
List<Map<String, Object>> backDataList = backData.getRows();
backDataListArray.add(backDataList);
}
}
catch (Throwable e)
{
System.err.println("Error: ");
System.err.println(e.getCause());
}
finally
{
Persistor.instance().closeSession();
}
// FOR EACH RECORD IN THE ORIGINAL QUERY, WRITE THE JSON STRING
for (int i = 0; i < graphDataList.size(); i++)
{
StringBuilder backDataString = new StringBuilder();
// BUILD THE BACK DATA STRING (IF THERE IS ANY)
for (int j = 0; j < backDataListArray.size(); j++)
{
List<Map<String, Object>> backDataList = (List<Map<String, Object>>) backDataListArray.get(j);
Map<String, Object> backDataBean = backDataList.get(i);
Map<String, Object> backSeriesBean = backSeriesList.get(j);
backDataString.append(backSeriesBean.get("the_series") + ": " + backDataBean.get("the_count") + ", ");
}
Map<String, Object> graphDataBean = graphDataList.get(i);
out.println("{the_quota: " + graphDataBean.get("the_quota") + ", " + "count_pt_year: " + graphDataBean.get("count_pt_year") + ", " + backDataString + "date_string: '" + graphDataBean.get("date_string") + "'}" + (i + 1 == graphDataList.size() ? "" : "," ));
}
【问题讨论】: