ThreadLocal在ssh框架中使用是相当广泛的:
·它被用于Hibernate3中的getCurrentSession()
·目的是为了解决session的transaction以及lazy问题
·currentsession是需要在hibernate.cfg.xml中配置的主要是两种方式(Thread/JTA)
·<property name="hibernate.current_session_context_class">thread</property>
·<property name="hibernate.current_session_context_class">jta</property>
·它还用在spring中的OpenSessionInView
·目的也是为了处理transaction
·当然还可以自己利用ThreadLocal手动控制session的关闭
·在web开发中可以使用filter来自己管理session
·第一:
package org.kker.drp.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 org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
*@author WYC
*@version 1.0
*/
public class HibernateSessionFilter implements Filter {
private static SessionFactory factory = null;
private static final ThreadLocal local = new ThreadLocal();
public void destroy() {
local.remove();
}
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(arg0, arg1);
Session session = (Session) local.get();
if (session != null && (session.isOpen())) {
try {
session.close();
//local.set(null);
local.remove();
} catch (HibernateException hibere) {
hibere.printStackTrace();
}
}
}
public void init(FilterConfig arg0) throws ServletException {
Configuration config = new Configuration().configure();
if (config != null) {
factory = config.buildSessionFactory();
System.err.println("init HibernateSessionFactory success!");
} else {
System.err.println("init HibernateSessionFactory error~!");
}
}
/**
* 使用ThreadLocal机制创建Session
*
* @return session {@link Session}
*/
public synchronized static Session getSession() {
Session session = session = (Session) local.get();
if (session != null) {
return session;
} else {
try {
session = factory.openSession();
local.set(session);
} catch (HibernateException hibere) {
hibere.printStackTrace();
}
return session;
}
}
}
·使用时直接:
Session session = HibernateSessionFilter.getSession();
·关闭时是HibernateSessionFilter自动完成
·使用ThreadLocal 可以有效的把session的关闭延迟到client与server一次会话的结束
·分页时会有二个基本变量
·offset、pagesize
·可以考滤一下 如果在页面与Action以及Dao之间来来回回的传递这两个小东西太烦琐了 并且影响项目今后的维护.
·大体思路
·使用一个SystemContext 类来存放我们的Action不需要但DAO层需要的变量或其它对象
·然后使用Filter来控制SystemContext类中的变量的值 (为SystemContext赋值/初使化)
·Dao层直接使用
·SystemContext.getOffset();等其它一个get方法 注意get方法是static的 因为使用ThreadLocal我们完全不需要注意synchronized(同步)问题.
·SystemContext类代码:
/**
* 使用ThreadLocal控制一次session时的变量使用
* @author WYC
* @version 1.0
*/
public class SystemContext {
public static final ThreadLocal offset = new ThreadLocal();
public static final ThreadLocal pagesize = new ThreadLocal();
/**
* @return the offset
*/
public static int getOffset() {
if(offset!=null){
return (Integer)offset.get();
}else{
return 0;
}
}
/**
* @return the pagesize
*/
public static int getPagesize() {
if(pagesize!=null){
return ((Integer)pagesize.get());
}else{
return (10);
}
}
public static void setPagesize(int _pagesize){
pagesize.set(_pagesize);
}
public static void setOffset(int _offset){
offset.set(_offset);
}
public static void setParameter(int _offset,int _pagesize){
offset.set(_offset);
pagesize.set(_pagesize);
}
}
·Filter类代码
import java.io.IOException;
import java.util.regex.Pattern;
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 javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.kker.oa.util.SystemContext;
public class PaginationFilter implements Filter {
private static Pattern pattern = Pattern.compile("//d+");
private static final Log log = LogFactory.getLog(PaginationFilter.class);
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httprequest = (HttpServletRequest) request;
HttpServletResponse httpresponse = (HttpServletResponse) response;
int offset = this.convertToInt(httprequest, "pager.offset");
int pagesize =(this.convertToInt(httprequest, "pagesize")<=0)?3:(this.convertToInt(httprequest, "pagesize"));
SystemContext.setParameter(offset, pagesize);
chain.doFilter(httprequest, httpresponse);
}
public void init(FilterConfig arg0) throws ServletException {
}
/**
* 返回指定name的requestScope 值
*
* @param request
* @param name
* @return
*/
private String getParameter4Request(HttpServletRequest request, String name) {
String temp = request.getParameter(name);
return temp;
}
/**
* 判断value是否为数字
*
* @param value
* @return true/false
*/
private boolean isInt(String value) {
if (value != null && pattern.matcher(value).matches()) {
return true;
}
log.debug("PaginationFilter-->isInt:"+value+"is NULL!");
return false;
}
/**
* 获得int值
*
* @param value
* @return
*/
private int convertToInt(HttpServletRequest request, String name) {
String temp = getParameter4Request(request, name);
if (isInt(temp)) {
return (Integer.parseInt(temp));
}
return 0;
}
}
·因为使用spring 的OpenSessionInView控制session Transaction 这里没有自定义控制session
·感谢http://blog.csdn.net/dongliheng/的正确理解ThreadLocal 文章