利用过滤器对hibernate的session治理,实现session在线程范围内的共享
利用过滤器对hibernate的session管理,实现session在线程范围内的共享hibernate中的Session关系到对数据库
利用过滤器对hibernate的session管理,实现session在线程范围内的共享
hibernate中的Session关系到对数据库的增删查改等基本的数据存取操作.对Session进行有效的维护,就像是在jdbc编程中对JDBC collection的维护.
???? 在struts+hibernate的方案中,常常利用过滤器(Filter)对session进行管理,以实现session在线程范围内的共享.为什么仅仅实现线程内的共享,是因为,不能把session用于多线程,否则会出现意外.在线程范围内实现sesion的共享.避免了session的频繁的创建和销毁.我看到有的程序中,在单个方法内,打开session,执行.关闭session.这显然没有在一次会话中有效的利用session
???? 下面的方案是.通过建立一个过滤器,以实现对sesion的共享:
package com.cs_oj.filter;import java.io.IOException;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Date;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 javax.servlet.http.HttpSession;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.hibernate.Session;import org.hibernate.Transaction;import com.cs_oj.data.dao.HibernateSessionFactory;public class HibernateSessionFilter implements Filter { private static final Log log = LogFactory.getLog(HibernateSessionFilter.class); public void destroy() { // TODO Auto-generated method stub } public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { log.debug("HibernateSessionFilter start"); Date date=new Date(); DateFormat df=new SimpleDateFormat("yyyy-MM-dd '时间--'HH:mm:ss"); System.out.println("----当前时间:"+df.format(date)+"----"); System.out.println("----------HibernateSessionFilter start-----------");//利用HibernateSessionFactory, 得到当 前线程中的session对象..HibernateSessionFactory的代码利用了ThreadLocal模式..详见..HibernateSessionFactory Session session=HibernateSessionFactory.getSession(); log.info("HibernateSessionFilter begin transaction"); System.out.println("HibernateSessionFilter begin transaction"); Transaction tx=session.beginTransaction(); //开始事务 log.debug("HibernateSessionFilter begin doChain"); HttpServletResponse response=(HttpServletResponse)arg1; try{ chain.doFilter(arg0, arg1); log.debug("HibernateSessionFilter begin commit"); //没有异常,则提交 try{ System.out.println("HibernateSessionFilter begin commit"); tx.commit(); System.out.println("HibernateSessionFilter commit success"); } catch(Exception e){ System.out.println("HibernateSessionFilter commit failed"); System.out.println("HibernateSessionFilter begin rollback() "); try{ System.out.println("HibernateSessionFilter begin rollback() "); tx.rollback(); System.out.println("HibernateSessionFilter rollback() success "); }catch(RuntimeException ex){ System.out.println("HibernateSessionFilter rollback() failed"); } } }catch (Exception e) { e.printStackTrace(); System.out.println("chain.doFilter(arg0, arg1) exception accurs "); System.out.println("HibernateSessionFilter begin rollback() "); tx.rollback(); //出现异常,回滚 //response.sendRedirect("error.jsp"); } finally{ log.debug("HibernateSessionFilter end doChain"); System.out.println("HibernateSessionFilter begin close session"); HibernateSessionFactory.closeSession(); System.out.println("*********HibernateSessionFilter close session success*********"); log.debug("HibernateSessionFilter begin close session"); //System.out.println("session.isOpen()="+session.isOpen()); } }}?
?
?
在web.xml文件中对上面的过滤器进行配置.
<filter> <filter-name>hibernateSession</filter-name> <filter-class>com.cs_oj.filter.HibernateSessionFilter</filter-class></filter><filter-mapping> <filter-name>hibernateSession</filter-name> <servlet-name>action</servlet-name> </filter-mapping><servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param>. <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>3</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>3</param-value> </init-param> <load-on-startup>0</load-on-startup></servlet><servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern></servlet-mapping>?
?
则对所有以.do作为后缀名的url,都会被过滤器过滤.在被过滤器过滤的action中,和业务层的方法内,只需要调用HibernateSessionFactory 的getSession()方法,得到当前线程内的session对象.用完session后,不要关闭session,而且,每次在用session进行添加和修改操作时,也不需要启动事务.
?
?
HibernateSessionFactory.java
?
package?com.cs_oj.data.dao; ????import?org.hibernate.HibernateException; ??import?org.hibernate.Session; ??import?org.hibernate.cfg.Configuration; ??????public?class?HibernateSessionFactory?{ ????????/**? ??????*?Location?of?hibernate.cfg.xml?file. ??????*?Location?should?be?on?the?classpath?as?Hibernate?uses? ??????*?#resourceAsStream?style?lookup?for?its?configuration?file.? ??????*?The?default?classpath?location?of?the?hibernate?config?file?is? ??????*?in?the?default?package.?Use?#setConfigFile()?to?update? ??????*?the?location?of?the?configuration?file?for?the?current?session.??? ??????*/??????private?static?String?CONFIG_FILE_LOCATION?=?"/hibernate.cfg.xml"; ??????private?static?final?ThreadLocal<Session>?threadLocal?=?new?ThreadLocal<Session>(); ??????private?static?Configuration?configuration?=?new?Configuration().configure(); ??????private?static?org.hibernate.SessionFactory?sessionFactory; ??????private?static?String?configFile?=?CONFIG_FILE_LOCATION; ????????private?HibernateSessionFactory()?{ ??????} ?????? ??????/** ??????*?Returns?the?ThreadLocal?Session?instance.?Lazy?initialize ??????*?the?<code>SessionFactory</code>?if?needed. ??????* ??????*?@return?Session ??????*?@throws?HibernateException ??????*/??????public?static?Session?getSession()?throws?HibernateException?{ ??????????Session?session?=?threadLocal.get(); ????????????if?(session?==?null?||?!session.isOpen())?{ ??????????????if?(sessionFactory?==?null)?{ ??????????????????rebuildSessionFactory(); ??????????????} ??????????????session?=?(sessionFactory?!=?null)???sessionFactory.openSession() ??????????????????????:?null; ??????????????threadLocal.set(session); ??????????} ????????????return?session; ??????} ????????/** ??????*?Rebuild?hibernate?session?factory ??????* ??????*/??????public?static?void?rebuildSessionFactory()?{ ??????????try?{ ??????????????//configuration.configure(); ??????????????sessionFactory?=?configuration.buildSessionFactory(); ??????????}?catch?(Exception?e)?{ ??????????????System.err ??????????????????????.println("%%%%?Error?Creating?SessionFactory?%%%%"); ??????????????e.printStackTrace(); ??????????} ??????} ????????/** ??????*?Close?the?single?hibernate?session?instance. ??????* ??????*?@throws?HibernateException ??????*/??????public?static?void?closeSession()?throws?HibernateException?{ ??????????Session?session?=?threadLocal.get(); ??????????threadLocal.set(null); ????????????if?(session?!=?null)?{ ??????????????session.close(); ??????????} ??????} ????????/** ??????*?return?session?factory ??????* ??????*/??????public?static?org.hibernate.SessionFactory?getSessionFactory()?{ ??????????return?sessionFactory; ??????} ????????/** ??????*?return?session?factory ??????* ??????*????session?factory?will?be?rebuilded?in?the?next?call ??????*/??????public?static?void?setConfigFile(String?configFile)?{ ??????????HibernateSessionFactory.configFile?=?configFile; ??????????sessionFactory?=?null; ??????} ????????/** ??????*?return?hibernate?configuration ??????* ??????*/??????public?static?Configuration?getConfiguration()?{ ??????????return?configuration; ??????} ????}??