在实际的任何一个系统中,查询都是必不可少的一个功能,而查询设计的好坏又影响到系统的响应时间和性能这两个关键指标,尤其是当数据量变得越来越大时,于是如何处理大数据量的查询成了每个系统架构设计时都必须面对的问题。本文将从数据及数据查询的特点分析出发,结合讨论现有各种解决方案的优缺点及其适用范围,来阐述J2EE平台下如何进行查询框架的设计。
Value List Handler模式及其局限性
在J2EE应用中,对于大数据量查询的处理有许多好的成功经验,比如Value List Handler设计模式就是其中非常经典的一个,见图1。该模式创建一个ValueListHandler对象来控制查询的执行以及结果集的缓存,它通过DAO(Data Access Object)来执行查询,并将数据库返回的结果集(传输对象Transfer Object的集合)缓存起来,接下来的客户端查询请求将直接从缓存中获得。它的特点主要体现在两点:服务器端缓存数据,每次只返回客户端本次操作所需的数据,通过这两个措施来减少数据库的访问次数以及增加客户端的响应速度,达到最优的查询效果。当然,这里面隐含一个前提就是客户端采用分页的方式来浏览数据。关于该模式的详细介绍,请参考[Core J2EE Patterns]一书。
图1:Value List Handler类图
但是在实际的应用过程中,会发现该模式存在一定的局限性,其实可以说是该模式应用具有一些前提条件:
1、由于缓存是以内存来换性能,这对于小数据量会工作得很好,但是如果结果集很大,内存消耗将会非常严重。同时,消耗在处理结果集上的时间也会越来越长,比如要循环读取记录集中的数据,然后依次填充每个传输对象,想想看几百万条数据这样处理起来肯定让人不能忍受。过长的处理时间不仅降低反应速度,同时还会占用宝贵的数据库连接资源,造成其它地方无连接可用。虽然,在DAO模式中利用CachedRowSet,Read Only RowSet ,RowSet Wrapper List等策略(详见参考资料)来代替Transfer Object Collection策略,有效地提高了处理速度,但是仍然存在着在大集合数据中进行定位、遍历等问题。试想一想,即使在CachedRowSet中的absolute(2000000)也是非常费时的操作。所有这一切的根源就在于缓存是一次性读取所有的数据,虽然有时你可以利用业务逻辑来强制性增加一些限制条件(比如产品查询必须选择大类和次类),但这种限制往往是不牢靠的或者说只是一时的权宜之计。也有人提出,可以不必缓存所有的查询结果,而采取只缓存部分结果集,比如500,1000条,但这样一来,就涉及到复杂的查询数据是否越界的控制,增加了复杂度,同时也不易实现。
2、既然使用缓存,那就不得不面对一个数据更新的问题,使用缓存,实际上就假定了在数据缓存期间,数据库中的数据不会改变,或者这些改变可以不被反映出来。但是,在很多场合下(比如常见的业务系统中)这些数据库中的数据经常会发生变化,而且这些改变需要及时反映给客户端。
3、缓存其实存在一个基本前提,就是缓存的数据会被客户端反复查询使用,具体到分页查询就是客户会选择不同的页数来查看数据。如果客户端的查询条件始终变化,或者用户基本上只关心第一页的数据(仔细琢磨一下用户的习惯,这在很多中应用场合都很常见),那缓存就失去了应有的意义,变得多此一举了。
数据分析
所以说,在决定是否应用某种设计模式前,我们需要对被查询数据的特点以及这些数据以何种方式被使用(查询的特点)进行一个分析,根据不同的结论来决定采用何种处理策略。而且,数据本身的特点和被使用的方式往往交织在一起,需要综合起来考虑,但这其中主要的考量点还是数据查询的特点。
一般来说,可以从以下几个方面来分析数据:
1、 数据量大。
这是我们今天讨论的数据的一个最基本特点,这个特点在查询框架设计时要引起足够的重视。
注意:大数据量的查询是指查询时匹配条件的数据量大,而不是指表中的数据量大,虽然大部分时候这两者都是一致的。因为在某些情况下,业务逻辑可以限制或者只需要一次获取很少量的数据,而查询的表中的数据量却可能很大,那这种情况就不属于本文的讨论范围。
2、 关联复杂,多表关联。
越是简单的数据可能关联越少,而越是复杂的数据往往都是多表关联,这样很多时候你需要将这几张表作为一个整体来考虑。
3、 变化频率。
从这个角度出发,可以大致将数据分为以下几类:几乎不变化的睡眠数据;有规律定时更新的数据,比如招聘网站的职位信息;经常性无规律更新的数据。
4、 成长性。
数据是否具有成长性,要预见数据的成长性,并在现有方案中考虑这种成长性,避免到时候查询框架的重新设计,象大部分的业务数据都具有这种成长性。
注意:这里也要特别注意区分数据本身的成长性和数据查询的成长性,这看似等同的两者其实还是存在很大的区别。就拿招聘网站来说,有效职位的数据肯定是一天天在增加,具有高成长性,但是在某个区间(比如一个月,一个星期)内的有效职位查询则变化不会太大,不具有成长性。而后者却往往是实际系统中最常遇到的查询情况。
5、 数据查询的频率和方式。
所有的数据查询不可能被等同地使用,你要分清楚系统中的几个关键查询,这些查询使用频率高,响应要快。试想一想,如果一个电子商务系统的产品查询每次都要让顾客等上十秒钟,结果就可想而知。
用户的使用习惯分析
除了对数据查询本身需要进行分析之外,我们还需要去分析一下用户如何来使用或者看待这些数据,用户的使用习惯如何。有人可能觉得这作用不大,或者很难去分析,其实查询的最终使用者是用户,他们的一些习惯会很大程度上左右你的设计。
1、 用户关心数据哪些方面的特性,不关心哪些方面的特性。
上面我们分析了数据本身的许多特性,那用户对其中哪些特性最敏感呢?比如说对脏数据特别不能接受,那我们就必须在查询框架设计时特别照顾到这一点。因为再好的框架设计都不可能在每个方面都能达到最优的效果,当必须有所取舍的时候,我们就要明白哪些特性是客户最关心的。
2、 用户如何来使用数据。
现在一般查询的客户端都采用分页的方式,一个查询可能会存在十几页甚至几十页结果。对于某些查询,用户可能往往只关心第一页或者前几页的结果,比如用户需要查询出最近完成的工单,而对于另外一些查询,用户可能对所有页结果都很关注,比如用户查询出最近三天新增的招聘职位。这不同类型的查询在查询框架设计的时候都需要有所考虑并给予不同的处理策略。
查询框架的设计
对数据及用户使用习惯进行了仔细的分析,接下来就可以根据这些分析来设计你的查询框架了。在J2EE架构下,对于大数据量的查询主要采取以下两种方法:
基于缓存的方式:
从数据库得到全部(部分)数据,并将其在服务器端进行缓存,接下来的客户端请求,将直接从缓存中取得需要的数据。这其实就是Value List Handler模式的原理,它主要适用于数据量不是非常大,变化不是很频繁(或者变化频繁但是有规律)且不具有成长性的情况,比如招聘网站或者电子商务网站的大部分查询就非常适合采取这种方式。
采用这种方式,要特别注意第一次查询问题,避免响应性能达不到要求,因为每个查询第一次都需要连接数据库,从中获取数据并缓存起来,所以第一次查询会比接下来的查询都显得更慢一些。
对于数据的缓存,有以下几种实现方式:
1 直接缓存在服务器端
Value List Handler模式就采取这种方式,并且可以根据不同的情况采取不同的缓存策略,比如Transfer Object集合,CachedRowSet等,这取决于你的DAO实现策略。
2 用临时表来保存查询结果
WLDJ(
www.sys-con.com/weblogic/)杂志2004年第7期上有一篇名为“Handling Large Database Result Sets”的文章,它详细介绍了如何利用临时表来改良Value List Handler模式以支持大型的J2EE应用。
当然除了以上这些方法以外,实现缓存也可以求助于操作系统的特定实现,以前我在IBM DW发表过一篇探讨MMF在Java中应用的文章(见参考资料),可惜未有深入,有兴趣的朋友可以参考一下。
在使用Value List Handler模式时,要特别注意以下几点:
1、 该模式一般和DAO模式搭配使用。
2、 该模式有POJO,stateful session bean两种实现策略。
3、 如果采取stateful session bean实现策略,则默认该缓存的时间长度为整个用户会话。
前面我们也提到过,如果数据不是绝对不变的,那缓存就面临更新的问题,一旦更新就可能存在着数据不一致,如果恰巧客户也希望能够看到变化的效果,这个时候就需要采取某种措施来保证这种一致性。常见的措施可以是设置一个标志位,每次发生数据更新后都将其对应的标志位更新,查询时如果发现标志位更新了,就直接从数据库获取数据,而不是从缓存中获取数据。另外一种方式就是数据更新的同时主动去清空session中的缓存,如果采用stateful session bean实现策略的话。
当然,采取缓存方式的大数据量查询一般来说都不大可能遇到设置更新标志位的问题,因为这种应用方式决定了数据不大可能变化,或者数据变化不要求立刻反应给用户。比如招聘网站新增加了一些职位信息,如果这些更新恰巧发生在某些用户的会话期间,且没有设置更新标志位,那这些新增信息就不会反应到用户的查询结果中,这种处理方式也是可以接受的
- 大小: 22.9 KB
分享到:
相关推荐
通过"J2EE综合案例开发PPT"的学习,你将掌握如何在实际项目中运用这些技术,理解它们之间的协作机制,以及如何通过配置文件和编程实现它们的功能。课程内容可能涵盖创建MVC结构的Web应用、实体类的设计与数据库映射...
在处理大数据量查询时,J2EE平台提供了一种经典的设计模式——Value List Handler模式,该模式主要用于提高查询效率和客户端响应速度。然而,这种模式在应对极端大数据量时会面临一些挑战和局限性。 首先,Value ...
本教程是关于J2EE开发的一份综合指南,它涵盖了多个核心技术和框架,旨在帮助开发者构建高效、可扩展的企业级应用程序。在这一部分中,我们将深入探讨以下关键组件: 1. **Struts框架**: Struts是Java Web开发中...
总的来说,《J2EE图书管理系统》是一个集成了多种技术的综合项目,涵盖了J2EE技术栈、SQL数据库和专业开发工具的使用,对于学习和实践Java Web开发具有很高的参考价值。通过深入理解和实践这个系统,开发者可以提升...
在学生信息管理系统中,mySQL存储了学生的个人信息、成绩、课程等相关数据,通过SQL查询语言进行数据的增删改查操作。mySQL的高并发处理能力和稳定的性能,确保了在大量用户访问下,系统仍能流畅运行。 系统的功能...
首先,J2EE的数据存取技术通常基于一个综合架构,例如采用Struts、Spring和Hibernate这三种框架的组合。Struts MVC和Spring MVC负责表示层,处理用户界面和业务逻辑间的交互。Spring则在业务层发挥作用,提供事务...
【描述】"J2EE大作业,分页实现,学校查询系统"揭示了这是一个针对J2EE技术的学习项目,可能作为教育机构或个人学习者提升J2EE开发技能的实践作业。系统的核心特性在于分页查询,这有助于提高用户界面的响应速度和...
- **大数据处理平台**:虽然轻量级J2EE框架主要用于构建Web应用,但结合Spring Batch等组件也能支持一定规模的大数据处理需求。 #### 五、总结 《轻量级J2EE企业应用实战第三版》是一本非常实用的技术书籍,不仅...
在J2EE系统中处理日期时间时,需要综合考虑系统的各个层面,包括用户界面、业务逻辑以及数据存储等。通过合理运用Java标准库提供的类和方法,可以有效地解决日期时间处理中的复杂问题。此外,还需要关注时区和夏令时...
通过学习实体、查询语言和持久化策略,可以有效地处理数据存储问题。 6. **设计模式与架构原则**:书中还可能探讨常见的设计模式,如工厂模式、单例模式、观察者模式等,以及如何利用这些模式来构建灵活、可维护的...
《精通J2EE—Eclipse Struts Hibernate Spring 整合应用案例源代码1》这个压缩包文件主要包含了一个基于J2EE平台的、利用Eclipse开发工具,整合Struts、Hibernate和Spring框架的综合应用案例的源代码。这些源代码是...
高校社团综合服务系统旨在提供一个高效、便捷的管理平台,以适应信息时代对数据处理的需求。通过这样的系统,可以简化社团信息管理,提高数据处理速度,便于管理者快速查询、存储和共享信息。此外,系统有助于提高...
在IT领域,构建一个基于j2EE(Java 2 Platform, Enterprise Edition)的网上书店是一项常见的实践,它涵盖了多种技术栈的综合运用,包括动态网页开发、数据库管理和服务器端逻辑处理。本项目以jsp(JavaServer Pages...
《轻量级 J2EE 企业应用实战:Struts+Spring+Hibernate 整合开发》是一本深入探讨Java企业级应用程序开发的书籍,主要聚焦于Struts、Spring和Hibernate这三大开源框架的集成与应用。这三大框架是Java开发中的核心...
总结,"j2EE在线交流聊天系统"是一个综合运用多种j2EE技术和工具构建的实时通讯平台,涉及到Web开发的基础和高级概念,如MVC架构、数据库操作、实时通信等,对于学习和实践j2EE开发有着重要的参考价值。
总的来说,"J2EE电子商务项目_需求与完成品"是一个涵盖了多种技术的综合实践,对于学习J2EE框架和电子商务系统开发的开发者来说,是一个宝贵的参考资料。通过这个项目,我们可以深入了解J2EE平台在实际项目中的应用...
总之,"j2EE购书系统原代码程序"是一个综合性的项目,涵盖了J2EE平台中的多种技术,包括但不限于Servlet、JSP、JDBC以及可能的EJB、MVC架构等,为学习者提供了深入了解J2EE开发实践的宝贵资源。通过分析和运行这个...