`
ihuashao
  • 浏览: 4553598 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

通过合理的设计下拉列表来调整页面显示性能!

阅读更多

如何设计下拉列表直接关系着页面显示的性能。

在应用程序设计的过程中,有很多的可选项,在通常的设计中这些可选项

会被设计为主表(Master Table),这些表中通常有三个字段:ID,名字,和说明。

有些时候为了区分先后顺序会追加一个字段用来表示排序的先后。

在使用这些主表中的内容的时候,需要从数据库中查询获得数据库中主表的最新内容,

之后这些内容作为options在页面上显示。

在通常情况下一个画面会涉及到两个业务操作的类,一个用来初始化页面的信息,另一个

用来处理画面的操作,将这些数据更新到数据库中。

在画面表示的时候,有些可选的内容,通常会从数据库中取得(通常是第一个业务操作类),之后显示。

如果某个应用程序中的这种内容非常多,那么每个页面显示的时候都需要从数据库中多次查询主表(Master Table)。

这样画面显示的时间就会非常的长。

那么可不可以将这些内容直接写入代码呢,主表中的内容虽然变更的不是很频繁,但是还是汇编更的。

所以将这些主表的内容写入到代码中是很不明智的,为了能够及时的反映主表的变更,所以这些内容必须

每次从数据库中取得。

那么有没有什么好的方法呢?

我们先从Web应用程序的内存驻留特点讲起。每一个应用程序启动的时候都会有一个叫做ApplicationContext

的上下文环境变量被创建,这个环境变量中存储着一些共同信息,例如Strut上的配置文件内容,Spring的配置文件

的内容。每次用户和服务器建立一个会话链接,服务器会为该用户创建一个Session Context的上下文环境,这个上下文

环境中放置着这个用户的一些信息,例如用户ID,用户名,所属部门等。每次用户向服务器发送一个请求,服务器都会将这个

请求构造成HttpRequest Context这样的上下文环境,将用户请求的信息放在其中。

降低页面显示时间的一个方法是,将数据库中的这些主表的信息放在内存中,每次页面显示的时候,不从数据库中取数据。

那么可以将这些数据放在哪里呢?很显然Application Context 和 SessionConext中都可以,但是考虑到主表内容通常

是所有用户多需要使用的,所以通常放在Application Context中即可。

那么什么时候将这些数据放在Application Context中呢?

Web Application中有一个特殊的接口,所有实现这个接口的类通过合理的配置将会在应用程序装载的时候执行,这个接口

就是:ApplicationContextListener

package com.jpleasure.util;

import java.util.Map;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MasterContextListener implements ServletContextListener {

@Override
public void contextDestroyed(ServletContextEvent arg0) {
// nothing
}

@Override
public void contextInitialized(ServletContextEvent ctxEnt) {
// load master records here
Map masters = loadMaster();
ctxEnt.getServletContext().setAttribute("master", masters);
}

private Map loadMaster() {
// load master rocoreds here
return null;
}

}

只需要在contextInitialized方法中将主表的数据放在其中即可。

在web.xml中配置:

<listener>
<listener-class>com.jpleasure.util.MasterContextListener</listener-class>
</listener>

如何从Application Context中取得数据呢?

package com.jpleasure.util;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

public class MasterReader {

public static List getMasterList(String key, HttpServletRequest request) {
Map masters = (Map)request.getSession().getServletContext().getAttribute("master");
List list = (List)masters.get(key);
return list;
}
}

有些时候为了方便使用,在MasterReader中添加一个静态变量对ServletContext的引用,在MasterContextListener

初始化的时候关联,在之后使用的过程中可以去掉request这个变量,毕竟不是哪里都可以得到这个变量的引用的。例如:

@Override
public void contextInitialized(ServletContextEvent ctxEnt) {
// load master records here
Map masters = loadMaster();
ServletContext ctx = ctxEnt.getServletContext();
MasterReader.setCtx(ctx);
ctx.setAttribute("master", masters);
}

package com.jpleasure.util;

import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

public class MasterReader {
private static ServletContext ctx = null;

public static ServletContext getCtx() {
return ctx;
}

public static void setCtx(ServletContext ctx) {
MasterReader.ctx = ctx;
}

public static List getMasterList(String key ) {
Map masters = (Map)ctx.getAttribute("master");
List list = (List)masters.get(key);
return list;
}
}

这个时候就需要关心一个问题了:数据库中的内容变更了怎么办?

一种方法是,增加一个Reresh方法,每次Master放生变更的时候,调用即可:

package com.jpleasure.util;

import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

public class MasterReader {
private static ServletContext ctx = null;

public static ServletContext getCtx() {
return ctx;
}

public static void setCtx(ServletContext ctx) {
MasterReader.ctx = ctx;
}

public static List getMasterList(String key ) {
Map masters = (Map)ctx.getAttribute("master");
List list = (List)masters.get(key);
return list;
}

public static List refresh(String key) {
//reload the master table associated with current key.
// then return the new master list
return getMasterList(key);
}
}

另外一种方法是使用一些定时工具每隔一定的时间自动调用所有的更新即可。

自动的方法可以使用Timer对象也可以使用蕾西Quartz这样的JOB Scheduler工具。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics