知方号

知方号

存储过程实现报表功能

存储过程实现报表功能

转至 http://136899184-qq-com.iteye.com.

问题提出

企业应用软件系统中报表功能几乎是必须的,业务数据都是通过报表、图表等形式展现给客户,这样的好处是能直观、快捷的让用户获得所需信息。通常,报表上展现的数据分散在不同的业务表中,一张报表对应有一条或者多条SQL语句来完成从不同的业务表中提取符合条件的数据,报表的复杂程度直接决定着SQL语句的复杂度,而且用户的报表经常会变动,这将产生了很多的维护工作,目前为止已经遇到的困难有如下这些:

1)用SQL实现报表功能,复杂的报表通常会写到几百行代码,现在我们写过最多的SQL已经有四百多行,用户报表改变时维护该条SQL语句困难、费时。

2)实现报表的SQL语句写在Java应用程序中,每次调用的时候都要发送到数据库服务器,并且重新编译,这给网络造成了压力,同时每次编译对性能也造成影响。

3)DAO实现类中编写的SQL语句修改后必须重启应用服务器才能将此次修改装载到内存中使用,重启应用服务必须在空闲时段完成。

4)运销系统报表展现工具使用ATGrid,而ATGrid支持的数据源只有ResultSet和Xml两种,我们采用的是ResultSet数据源。Hibernate在DAO层必须将session关闭才能释放数据库连接,这样返回给ATGrid的数据源rs是一个空引用,没有指向任何资源,所以取不到任何数据,只有session不关闭才能取到数据,但是这样数据库连接被挂起,不能释放。

引入存储过程可以解决以上四个问题。

存储过程介绍

存储过程是由流控制和SQL语句集书写的过程,这个过程经编译和优化后存储在数据库服务器中,应用程序使用时只要调用即可。它具有以下优点:

1)存储过程的能力大大增强了SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算,如解决报表问题。

2)在运行存储过程前,数据库已对其进行了语法和句法分析,并给出了优化执行方案。这种已经编译好的过程可极大地改善SQL语句的性能。由于执行SQL语句的大部分工作已经完成,所以存储过程能以极快的速度执行。

3)可以降低网络的通信量。

4)使体现企业规则的运算程序放入数据库服务器中,以便集中控制。当企业规则发生变化时在服务器中改变存储过程即可,无须修改任何应用程序。

报表存储过程设计

存储过程实现报表功能主要思想集中在临时表上,即每张用户报表对应一张临时数据表,该临时数据表的字段和报表表头要求的指标一一对应。

Oracle的临时表分为两种,事务级别临时表和Session级别临时表,此设计中使用Session级别临时表,使用Session级别临时表的好处在于其中的数据是Session级别隔离的,不同用户请求的数据相互隔离,互不干扰,每次用户访问报表时,存储过程将符合条件的数据从不同的物理表中抓取到临时数据表中,并且直接从临时数据表中返回数据给用户。

由于运销系统中使用apache的dbcp数据库连接池组件,应用服务器(Tomcat)启动时,就已经与Oracle创建了配置文件中指定数量的连接,此连接会持有Session会话,造成临时表中数据不会即时删除,而连接池又是应用服务器(Tomcat)自己管理的,多线程访问时,数据库连接被分配给线程是随机的,所以会出现数据访问错误的情况,引入临时参数表可以解决以上问题。

临时参数表也是Session级别的,它和临时数据表是同时被一个连接访问的,所以它们的Session隔离应该是同步的。临时参数表中存储的是调用存储过程的参数列表,当调用存储过程时,首先将此次调用的参数列表与临时参数表中的参数列表比较,如果临时参数表中没有记录或者比较不相等时则将此次调用的参数列表写入到临时参数表中,同时将符合条件的数据写入临时数据表中,并且从临时数据表中返回符合条件的数据给Java应用程序,下次调用存储过程时,如果参数列表相同,则直接从临时数据表中返回数据给Java应用程序,这样可以起到缓存的作用,提高存储过程效率。

为什么Hibernate Session能关闭

SQL语句实现报表使用的Statement和ResultSet为:

class org.apache.commons.dbcp.DelegatingStatement

class org.apache.commons.dbcp.DelegatingResultSet

存储过程实现报表使用的Statement和ResultSet为:

class org.apache.commons.dbcp.DelegatingCallableStatement

class oracle.jdbc.driver.OracleResultSetImpl

由于ResultSet接口的实现方式不同,造成ResultSet类型的引用变量rs所指向的资源释放时机不同。

性能测试

按照以上设计方式实现存储过程后,使用JMeter进行了性能测试,测试结果显示,在大并发量的情况下,使用存储过程比使用SQL语句性能更好。测试数据如下表所示:

Label # Samples Average Median 90% Line

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至lizi9903@foxmail.com举报,一经查实,本站将立刻删除。