ThreadLocal分页逻辑的封装处理(转)_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > ThreadLocal分页逻辑的封装处理(转)

ThreadLocal分页逻辑的封装处理(转)

 2014/3/24 18:49:46  fangguanhong  程序员俱乐部  我要评论(0)
  • 摘要:分页逻辑的封装处理(请参考AbstractManager.java)ThreadLocal设计模式,线程局部变量,因为每一次请求都对应一个线程,把初始化的分页数据放在这个局部变量中当用到时,直接从当前线程中获取。原理同HibernateOpenSessionInView.为避免在Action(呈现层)和Manager(业务逻辑层)之间传递大量的参数,可以使用ThreadLocal模式来传递分页参数(包括:offset和pagesize)。-定义:参考SystemContext.java
  • 标签:thread
分页逻辑的封装处理(请参考AbstractManager.java)
ThreadLocal设计模式线程局部变量,因为每一次请求都对应一个线程,把初始化的分页数据放在这个局部变量中
当用到时,直接从当前线程中获取。原理同HibernateOpenSessionInView.
为避免在Action(呈现层)和Manager(业务逻辑层)之间传递大量的参数,
可以使用ThreadLocal模式来传递分页参数(包括:offset和pagesize)。
-定义:参考SystemContext.java
-往ThreadLocal中赋值:参考PagerFilter.java
-从ThreadLocal中获取分页参数:参考AbstractManager.java

-------------------------------------------------------------
具体代码如下:
1.定义分页数据封装类
package com.feihu.oa.page;
import java.util.List;
public class PagerModel
{
private List datas; // 分页数据列表
private int total; // 查询总记录数
public List getDatas()
{
  return datas;
}
public void setDatas(List datas)
{
  this.datas = datas;
}
public int getTotal()
{
  return total;
}
public void setTotal(int total)
{
  this.total = total;
}
}
2.使用ThreadLocal存储分页起始索引记录位置 与 分页页面显示的记录数
package com.feihu.oa.page;
public class SystemContext {
private static ThreadLocal offset = new ThreadLocal(); //记录起始索引位置
private static ThreadLocal pagesize = new ThreadLocal(); //每页显示多少条记录

public static void setOffset(int _offset){
  offset.set(_offset);
}

public static int getOffset(){
  Integer _offset = (Integer)offset.get();
  if(_offset == null){
   return 0;
  }
  return _offset;
}

public static void removeOffset(){
  offset.remove();
}

public static void setPagesize(int _pagesize){
  pagesize.set(_pagesize);
}

public static int getPagesize(){
  Integer _pagesize = (Integer)pagesize.get();
  if(_pagesize == null){
   return Integer.MAX_VALUE;
  }
  return _pagesize;
}

public static void removePagesize(){
  pagesize.remove();
}
}


3.定义分页逻辑处理封装类AbstractManager.java
--------------------------------------------------------------------------
package com.feihu.dao;

import java.util.List;
import org.hibernate.Query;
import com.feihu.oa.manager.SystemException;
import com.feihu.oa.page.PagerModel;
import com.feihu.oa.page.SystemContext;
public abstract class AbstractManager extends MyDaoSupport
{

public PagerModel searchPaginated(String hql){
  return searchPaginated(hql, null);
}

public PagerModel searchPaginated(String hql,Object value){
  return searchPaginated(hql, new Object[]{value});
}

public PagerModel searchPaginated(String hql,Object[] values){
  return searchPaginated(hql, values, SystemContext.getOffset(), SystemContext.getPagesize());
}

public PagerModel searchPaginated(String hql,int offset,int pagesize){
  return searchPaginated(hql, null, offset, pagesize);
}

public PagerModel searchPaginated(String hql,Object value,int offset,int pagesize){
  return searchPaginated(hql, new Object[]{value}, offset, pagesize);
}

public PagerModel searchPaginated(String hql,Object[] values,int offset,int pagesize)
{
  String countHql = getCountQuery(hql);//使用传递进来的hql语句 构造出查询总记录数的语句
  Query query = getSession().createQuery(countHql);//创建hql查询语句,获取总记录数,要用session,getHibernateTemplate没有此方法
  if(values != null && values.length > 0)
  {
   for(int i = 0; i<values.length;i++)
   {
    query.setParameter(i, values[i]);
   }
  }
  int total = ((Long)query.uniqueResult()).intValue(); //返回结果只有一个时可用此方法
 
  query = getSession().createQuery(hql);//创建查询语句以获取数据集合
  query.setFirstResult(offset); //设置hibernate查询开始索引
  query.setMaxResults(pagesize); //设置hibernate查询多少条记录
  List datas = query.list();  //得到查询数据结果列表集合
 
  PagerModel pm = new PagerModel();
  pm.setDatas(datas); //将结果集合设置进 封装好的 分页类
  pm.setTotal(total);  //将总记录数设置进  分页类
  return pm;
}
//
//
private String getCountQuery(String hql)
{
  int index = hql.indexOf("from");
  if(index!=-1)
  {
   return "select count(*) " + hql.substring(index);//hql语句中,只有查询总记录数才能用select count(*)这样的写法
  }
  throw new SystemException("无效的HQL查询语句【"+hql+"】","exception.hql.query");
}
}
++++++++++++++++++++++++++++++++++++
涉及到的其他类如下:
++++++++++++++++++++++++++++++++++++
package com.feihu.dao;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public abstract class MyDaoSupport extends HibernateDaoSupport
{
private SessionFactory mySessionFacotry; 
    @Resource
    public void setMySessionFacotry(SessionFactory sessionFacotry) { 
        this.mySessionFacotry = sessionFacotry; 
    } 
    @PostConstruct
    public void injectSessionFactory() { 
        super.setSessionFactory(mySessionFacotry); 
    }
}
+++++++++++++++++++++++++++++++
异常信息自定义
package com.feihu.oa.manager;
public class SystemException extends RuntimeException
{
//异常代码关键字,其值在MessageResources.properties文件定义
String key;
//可以输出一些异常时的参数
Object[] values;
public String getKey()
{
  return key;
}
public SystemException(String message,String key)
{
  super(message);
  this.key=key;
  // TODO Auto-generated constructor stub
}
public SystemException()
{
  super();
  // TODO Auto-generated constructor stub
}
public SystemException(String message, Throwable cause)
{
  super(message, cause);
  // TODO Auto-generated constructor stub
}
public SystemException(String message)
{
  super(message);
  // TODO Auto-generated constructor stub
}
public Object[] getValues()
{
  return values;
}
public SystemException(Throwable cause)
{
  super(cause);
  // TODO Auto-generated constructor stub
}
public SystemException(String message,String key,Object[] values)
{
  super(message);
  this.key = key;
  this.values = new Object[]{values};
  // TODO Auto-generated constructor stub
}

public SystemException(String message,String key,Object value)
{
  super(message);
  this.key = key;
  this.values = new Object[]{value};
  // TODO Auto-generated constructor stub
}
}
++++++++++++++++++++++++++++++++++++++++++
异常信息处理类
package com.feihu.oa.web.action;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ExceptionHandler;
import org.apache.struts.config.ExceptionConfig;
import com.feihu.oa.manager.SystemException;
public class SystemExceptionHandler extends ExceptionHandler
{
@Override
public ActionForward execute(Exception ex, ExceptionConfig ae, ActionMapping mapping, ActionForm formInstance, HttpServletRequest request, HttpServletResponse response) throws ServletException
{
  ActionForward forward = null;
  if(ae.getPath() != null)
  {
   forward = new ActionForward(ae.getPath());
  }else
  {
   forward = mapping.getInputForward();
  }
   if (ex instanceof SystemException)
  {
    SystemException sysex = (SystemException) ex;
    String key = sysex.getKey();
    ActionMessage error = null;
    if(key==null)
    {
     error= new ActionMessage(sysex.getKey(),sysex.getMessage());
    }else if(sysex.getValues()!=null)
    {
     error=new ActionMessage(key,sysex.getValues());
    }
    this.storeException(request, key, error, forward, ae.getScope());
  
  }
  return super.execute(ex, ae, mapping, formInstance, request, response);
}
}
++++++++++++++++++++++++++++++++++++++++++
struts-config.xml文件配置
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
          "http://struts.apache.org/dtds/struts-config_1_3.dtd">
<struts-config>

<form-beans>
  <form-bean name="orgform"
   type="com.feihu.oa.web.formbean.OrgForm">
  </form-bean>
</form-beans>
<global-exceptions>
  <exception key="errors.detail"
   type="com.feihu.oa.manager.SystemException"
   path="/common/exception.jsp" scope="request"
   handler="com.feihu.oa.web.action.SystemExceptionHandler" />
</global-exceptions>
<action-mappings>
  <action path="/org" parameter="method" name="orgform">
   <!-- struts异常自动处理 -->
   <!--   <exception key="errors.detail" type="java.lang.RuntimeException" path="/common/exception.jsp" scope="request"/>
   -->
   <!-- 自定义异常 -->
   <forward name="index" path="/org/index.jsp"></forward>
   <forward name="add_input" path="/org/add_input.jsp"></forward>
   <forward name="add_success"
    path="/common/pub_add_success.jsp">
   </forward>
   <forward name="del_success"
    path="/common/pub_del_success.jsp">
   </forward>
   <!--  forward name="exception" path="/common/exception.jsp"></forward>-->
  </action>
</action-mappings>
<controller><!-- spring提供的,用于管理 structs请求的action,控制器根据当前的action的path寻找bean,用bean对应的action处理请求 -->
  <set-property property="processorClass"
   value="org.springframework.web.struts.DelegatingRequestProcessor" />
</controller><!--配置spring控制器-->
<!-- 使用异常机制时要定义这个资源树文件 -->
<message-resources parameter="MessageResources"></message-resources>
</struts-config>

-------------------------------------------------------------------------------
4.定义PagerFilter过滤类,从TreadLocal中获取并设置初始化分页参数

package com.feihu.web.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import com.feihu.oa.page.SystemContext;

public class PagerFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
   FilterChain chain) throws IOException, ServletException {
 
  HttpServletRequest httpRequest = (HttpServletRequest)request;
 
  SystemContext.setOffset(getOffset(httpRequest));
  SystemContext.setPagesize(getPagesize(httpRequest));
 
  try{
   chain.doFilter(request, response);
  }finally{
   SystemContext.removeOffset();
   SystemContext.removePagesize();
  }
}

private int getOffset(HttpServletRequest request){
  int offset = 0;
  try {
   offset = Integer.parseInt(request.getParameter("pager.offset"));
  } catch (Exception ignore) {
  }
  return offset;
}

private int getPagesize(HttpServletRequest request){
  return 10;
}
public void init(FilterConfig arg0) throws ServletException {
}
}
-----------------------------------------------------------------------------
5.配置web.xml文件,将过滤类加入到web.xml文件中
<filter>
  <filter-name>PagerFilter</filter-name>
  <filter-class>com.feihu.web.filter.PagerFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>PagerFilter</filter-name>
  <url-pattern>
@Override
protected ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
{
  OrgForm formbean = (OrgForm)form;
  Integer parentId = formbean.getParentId();
  request.setAttribute("orgs", orgManager.searchOrgs(parentId));
 
  int ppid=0;
  if(formbean.getParentId()!=null && formbean.getParentId()>0)
  {
   Organization org = orgManager.findOrg(formbean.getParentId());
   Organization parent = org.getParent();
   if(parent!=null)
   {
    ppid = parent.getId();
   }
  }
  request.setAttribute("ppid", ppid);
  return mapping.findForward("index");
}
public ActionForward addInput(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
{
 
  return mapping.findForward("add_input");
}
public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
{
  OrgForm formbean = (OrgForm)form;
  Integer parentId=formbean.getParentId();
  Organization org = new Organization();
  BeanUtils.copyProperties(org, formbean);

  return mapping.findForward("add_success");
}
public ActionForward del(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
{
  OrgForm formbean = (OrgForm)form;
 

  return mapping.findForward("del_success");
}
}
上一篇: [NIO.2] 定义 Path 类 下一篇: 没有下一篇了!
发表评论
用户名: 匿名