Spring批量查询

对于大批量数据查询,我们需要绕开Hibernate API,直接使用JDBC.使用SpringJdbcTemplatequeryForList()方法也是很好的选择.当然整合好Spring,StrutsHibernate是一门艺术,需要在实践中不断的总结和领略它们的风采.

业务说明:统计出一段时间内,全市每个缴费区域各种数据类型的记录数.在页面通过表格的形式显示出来,没有记录的通过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的魅力.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值