背景
在Java/J2EE领域,JDBC是访问关系型数据库的标准。在O/R Mapping技术出来前,开发者需要直接借助于JDBC和SQL进行RDBMS操作。在一切都是对象的思想下(From Thinking in Java),Java无法忍受使用面向对象语言来访问关系型数据库,O/R Mapping 技术应运而生。借助于O/R Mapping技术,能将对象属性映射到RDBMS表的列、将对象映射到RDBMS表,这些Mapping技术能为应用自动创建高效的SQL语句。此外,O/R Mapping技术还提供了延迟装载、(分布式)缓存等高级特征。使用O/R Mapping技术,能大量节省开发时间,减少代码量及开发成本。
问题提出
最近在公司使用SSH开发项目 (Sping, Struts, Hibernate)开发项目,其中我负责统计报表部分。
问题详述如下:
在一个表单t_manhour中,有用字段如下
-
id int not null primary key,
-
employee char(20),
-
thisDate char(20),
-
opac char(10),
-
month int,
-
workcenter char(20),
-
hours double
具体解释,对于一个Employee, 他以工种opac,在工作中心workcenter工作了hours的时间。于此表对应的bean是ManHour
要求:
前台jsp页面返回数据如下所示
图表1: 显示数据
需要按照opac(也就是métier)工种分组,显示每人每月工作时间之和。
最初的解决办法
在action中可以获取bean所有实例,然后对每个实例进行处理,将数据存放到多层HashMap中,
-
HashMap<String,HashMap<String,HashMap<Integer, Double>>>
第一个String是工种,第二个是人员名称,第三个是月份。
总之,咋看之下,不是那么难实现,但是其中问题显而易见。
1,每月工作日期肯定不为单,所以涉及到求和的时候,就需要对这个多层HashMap进行更新,每次需要查找三次Key才能找到某人以某种工种,在某月工作了多久,然后才能进行求和()
效率低下
2,特别是显示到jsp的时候,更需要先求出键值的Set,然后循环遍历,根据键值求出所对应的值,因为键值也是我们需要显示的内容。
问题解决
HQL
想了好久,晚上吃饭的时候,跟女朋友说了这个情况,在她的提醒下,我恍然想起,还有HQL一说。
使用过SQL语言的同学一定不陌生。Hibernate Query Language
-
Select
-
m.employee, m.opac, m.month,sum(m.hours)
-
from ManHour m
-
Group by m.opac, m.employee, m.month
-
Order by m.opac, m.employee, m.month
这样,直接先根据工种分组,在根据人员分组,再根据月份分组,sum()可以直接求出最小分组中所有时间之和。
返回的是一个List,list的每个节点都是一个Object[]数组,数组大小等于你想显示的列的个数。
简单,速度快。
总结
不要忘了最基础的,同时也是很有效率的。
HQL估计他的产生也是因为O/R Mapping不适合解决统计之类的问题。
阅读(4896) | 评论(4) | 转发(0) |