,我们需要绕开Hibernate API,直接使用JDBC.使用Spring中JdbcTemplate的queryForList()方法也是很好的选择.当然整合好Spring,Struts和Hibernate是一门艺术,需要在实践中不断的总结和领略它们的风采.

业务说明:统计出一段时间内,全市每个缴费区域各种数据类型的记录数.在页面通过表格的形式显示出来,没有记录的通过0填充.如图


区县

业务1变更

业务2变更

业务3变更

业务4变更

区县1

0

0

0

0

区先2

2

0

2

0

全市

2

0

2

0


hibernate实现的代码

payarea存放着各个缴费区域

datatype存放着各个数据类型

for (int i = 0; i < payarea.length; i++) { List<Integer> listTemp = new ArrayList<Integer>(); for (int j = 0; j < datatype.length; j++) { int count = mgr.countReportInfo(payarea[i].toString(), datatype[j].name(), start, end); listTemp.add(count); } countMap.put(payarea[i].toString(), listTemp); }

上面方法调用的方法

public int countReportInfo(String payArea, String dataType, Date startDate, Date endDate) { List<Object> params = new ArrayList<Object>(); int amount = 0; StringBuffer hql = new StringBuffer( "select count(*) from InfoReportHis ir where 1=1 "); if (payArea != null && !"".equals(payArea) && !PayArea.全市.toString().equals(payArea)) { hql.append(" and ir.payArea = ? "); params.add(payArea); } if (dataType != null && !"".equals(dataType)) { hql.append(" and ir.dataType = ? "); params.add(dataType); } if (startDate != null) { hql.append(" and ir.dealTime >= ?"); params.add(startDate); } if (endDate != null) { hql.append(" and ir.dealTime <= ?"); params.add(endDate); } List list = dao.getObjectByCondtions(hql.toString(), params.toArray(), null, null); if (!CommonUtil.isNullOrSizeZero(list)) { amount = Integer.parseInt((list.get(0)).toString()); } return amount; }

for循环遍历全市下每个缴费区域的数据类型,每一次循环都要调用countReportInfo方法返回记录数,最后存放到Map中.

10秒左右,这是用户根本不能忍受的.原因是HQL查询是面向对象的查询的方法,中间有一个映射转换,这不是最重要的.最重要的是两个for循环.每次循环需要不断的调用方法,不断的和数据库交换数据.这种做法不仅需要消耗大量的资源,还和费时间.为此我们使用Spring提供的方法


Spring重写的代码,统计速度有本质的提升

SQL语言查询出每个缴费区域下有记录的数据类型的记录数

public Map<String, Map<String, String>> countReportInfo(Date startDate, Date endDate) { String sql = "select t.pay_area as area, t.data_type as type,count('X') as num" + " from info_report_his t" + " where deal_time >=? and deal_time <=?" + " group by t.pay_area, t.data_type" + " order by t.pay_area, t.data_type desc"; List list = jdbcDao.getJdbcTemplate().queryForList(sql, new Object[] { startDate, endDate }); //由于返回的是list,为了能够按照表格的形式在页面中显示,我们需要对list重新组装 //这里我们使用了Map<String, Map<String, String>>的数据结构来封装所有的数据 //值得注意的是这里的Map是TreeMap,因为需要按照字典顺序排列 return this.showCountReportInfo(list); }

上面方法调用的方法

private Map<String, Map<String, String>> showCountReportInfo(List list) { // 初始化"表格",给每个"单元格"赋值默认为0 Map<String, Map<String, String>> map = new TreeMap<String, Map<String, String>>(); for (PayArea area : PayArea.values()) { Map<String, String> dataTypeMap = new TreeMap<String, String>(); for (InfoReportDataCountType type : InfoReportDataCountType .values()) { dataTypeMap.put(type.name(), "0"); } map.put(area.toString(), dataTypeMap); } Iterator it = list.iterator(); while (it.hasNext()) { Map tempMap = (Map) it.next(); String AREA = tempMap.get("AREA").toString(); String TYPE = tempMap.get("TYPE").toString(); String NUM = tempMap.get("NUM").toString(); // 获得"全市"所对应TYPE的值 int initAllSum = Integer.parseInt(map.get(PayArea.全市.toString()) .get(TYPE)); // 将所有区县对应的TYPE累加到allSum中 String allSum = String.valueOf(initAllSum + Integer.parseInt(NUM)); // 将累加后的值写回"全市"对应TYPE中 map.get(PayArea.全市.toString()).put(TYPE, allSum); map.get(AREA).put(TYPE, NUM); } return map; }

,原因是:通过一条sql语言直接面向数据库查询出来,然后对查询出来的数据进行了包装,这个包装有点像”适配器”,也符合软件开发的思想.在这里我们也领略到了Spring的魅力.