如上图所示,我们在开发中可能经常会碰到这样的结构要求,这里的需求是列出各个市场活动下面的周报列表(具体数据结构如下),待查数据表所涉及的字段主要为市场活动名称与周报id,那么如何将这种数据做成下面这样有层级的结构返回到前台呢?
[
{ "marketActivityName": [string], // 市场活动名称 "marketActivityWeeklyReportIds": [[string],...] // 市场活动周报Id }
]
方案一:
分两次请求数据。先查出各个市场活动,当用户选择某一市场活动之后将市场活动id回传到后台再查出相应的周报列表。设计到的两个数据结构如下:
(1) 第一次请求返回结果: [ { "marketActivityName": [string], // 市场活动名称 "marketActivityId": [string] // 市场活动 Id } ] (2) 第二次请求返回结果: [[string],...] // 市场活动周报Id
当然上面的结果也可能在后台拼接成我们开始想要的结构再返回给前端,即先查出市场活动,再在遍历市场活动的结果集时,根据市场活动 id 查出相应的周报 id 组。但这种循环中嵌套数据库操作的做法是
我们日常开发需要避免的,所以并不推荐这种做法。
方案二:
public class MarketActivityWeekListVO {
private String marketActivityName; private List<String> marketActivityWeeklyReportIds; public String getMarketActivityName() { return marketActivityName; } public void setMarketActivityName(String marketActivityName) { this.marketActivityName = marketActivityName; } public List<String> getMarketActivityWeeklyReportIds() { return marketActivityWeeklyReportIds; } public void setMarketActivityWeeklyReportIds( List<String> marketActivityWeeklyReportIds) { this.marketActivityWeeklyReportIds = marketActivityWeeklyReportIds; } }
// 核心方法 public List<MarketActivityWeekListVO> getMarketActivityWeekReportList() { // 这里先给一个经销商Id,后面再从cookie中拿 String dealerId = "1baf88c0-7404-11e6-8da9-005056af50a8"; // 这里选择按创建日期一次性查出所有报表类型 MarketActivityReportWeekExample weekReportExample = new MarketActivityReportWeekExample(); weekReportExample.setOrderByClause("create_time DESC"); weekReportExample.createCriteria().andIstotalEqualTo(BaseConstant.MARKET_ACTIVITY_TOTAL_FALSE).andDealerIdEqualTo(dealerId); List<MarketActivityReportWeek> reportWeekList = marketActivityReportWeekMapper.selectByExample(weekReportExample); // 先用一个map去接收结果(核心代码) Map<String,List<String>> weekReportMap = new HashMap<String, List<String>>(); List<String> reportIdList = null; for (MarketActivityReportWeek report : reportWeekList) { String marketActivityName = report.getMarketActivityName(); if (weekReportMap.containsKey(marketActivityName)) { reportIdList = weekReportMap.get(marketActivityName); reportIdList.add(report.getId()); } else { reportIdList = new ArrayList<String>(); reportIdList.add(report.getId()); weekReportMap.put(marketActivityName, reportIdList); } } // 总模型 List<MarketActivityWeekListVO> marketActivityWeekListVOList = new ArrayList<MarketActivityWeekListVO>(); // 数据转移 for (Map.Entry<String, List<String>> entry : weekReportMap.entrySet()) { MarketActivityWeekListVO marketActivityWeekListVO = new MarketActivityWeekListVO(); marketActivityWeekListVO.setMarketActivityName(entry.getKey()); marketActivityWeekListVO.setMarketActivityWeeklyReportIds(entry.getValue()); marketActivityWeekListVOList.add(marketActivityWeekListVO); } return marketActivityWeekListVOList; }
这里在从数据库查出结果集后,先用一个 map 去接收数据,利用容器的特殊结构和判断方法,最终将数据做成我们想要的结果返回到前台。
类似的问题会经常出现在那种数据库保存时不存在层级结构,但实际页面展示有相应需求的问题中,方案二的方法很巧妙了利用了 map 的特殊结构,避免了对数据库的不必要操作,还是很有参考价值的。