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