用Filter对Hibernate的session进行管理
2009-08-05 15:12
295 查看
关键字: hibernate, session
,Filter
hibernate中的Session关系到对数据库的增删查改等基本的数据存取操作.对Session进行有效的维护,就像是在jdbc编程中对JDBC collection的维护.
在struts+hibernate的方案中,常常利用过滤器(Filter)对session进行管理,以实现session在线程范围内的共享.为什
么仅仅实现线程内的共享,是因为,不能把session用于多线程,否则会出现意外.在线程范围内实现sesion的共享.避免了session的频繁的
创建和销毁.我看到有的程序中,在单个方法内,打开session,执行.关闭session.这显然没有在一次会话中有效的利用session
下面的方案是.通过建立一个过滤器,以实现对sesion的共享:
Java代码
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();
Transaction tx=session.beginTransaction();
//开始事务
log.debug(
"HibernateSessionFilter begin doChain"
);
HttpServletResponse response=(HttpServletResponse)arg1;
try
{
chain.doFilter(arg0, arg1);
//没有异常,则提交
try{
tx.commit();
}
catch
(Exception e){
try
{
tx.commit();
}
catch
(RuntimeException ex){
System.out.println(
"HibernateSessionFilter rollback() failed"
);
}
}
}
catch
(Exception e) {
e.printStackTrace();
tx.rollback();
//出现异常,回滚
//response.sendRedirect("error.jsp");
}
finally
{
HibernateSessionFactory.closeSession();
}
}
}
在web.xml文件中对上面的过滤器进行配置.
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
Java代码
package
com.cs_oj.data.dao;
import
org.hibernate.HibernateException;
import
org.hibernate.Session;
import
org.hibernate.cfg.Configuration;
public
class
HibernateSessionFactory {
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() {
}
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;
}
public
static
void
rebuildSessionFactory() {
try
{
sessionFactory = configuration.buildSessionFactory();
}
catch
(Exception e) {
System.err
.println(
"%%%% Error Creating SessionFactory %%%%"
);
e.printStackTrace();
}
}
public
static
void
closeSession()
throws
HibernateException {
Session session = threadLocal.get();
threadLocal.set(
null
);
if
(session !=
null
) {
session.close();
}
}
public
static
org.hibernate.SessionFactory getSessionFactory() {
return
sessionFactory;
}
public
static
void
setConfigFile(String configFile) {
HibernateSessionFactory.configFile = configFile;
sessionFactory =
null
;
}
public
static
Configuration getConfiguration() {
return
configuration;
}
}
,Filter
hibernate中的Session关系到对数据库的增删查改等基本的数据存取操作.对Session进行有效的维护,就像是在jdbc编程中对JDBC collection的维护.
在struts+hibernate的方案中,常常利用过滤器(Filter)对session进行管理,以实现session在线程范围内的共享.为什
么仅仅实现线程内的共享,是因为,不能把session用于多线程,否则会出现意外.在线程范围内实现sesion的共享.避免了session的频繁的
创建和销毁.我看到有的程序中,在单个方法内,打开session,执行.关闭session.这显然没有在一次会话中有效的利用session
下面的方案是.通过建立一个过滤器,以实现对sesion的共享:
Java代码
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();
Transaction tx=session.beginTransaction();
//开始事务
log.debug(
"HibernateSessionFilter begin doChain"
);
HttpServletResponse response=(HttpServletResponse)arg1;
try
{
chain.doFilter(arg0, arg1);
//没有异常,则提交
try{
tx.commit();
}
catch
(Exception e){
try
{
tx.commit();
}
catch
(RuntimeException ex){
System.out.println(
"HibernateSessionFilter rollback() failed"
);
}
}
}
catch
(Exception e) {
e.printStackTrace();
tx.rollback();
//出现异常,回滚
//response.sendRedirect("error.jsp");
}
finally
{
HibernateSessionFactory.closeSession();
}
}
}
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文件中对上面的过滤器进行配置.
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
>
<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
Java代码
package
com.cs_oj.data.dao;
import
org.hibernate.HibernateException;
import
org.hibernate.Session;
import
org.hibernate.cfg.Configuration;
public
class
HibernateSessionFactory {
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() {
}
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;
}
public
static
void
rebuildSessionFactory() {
try
{
sessionFactory = configuration.buildSessionFactory();
}
catch
(Exception e) {
System.err
.println(
"%%%% Error Creating SessionFactory %%%%"
);
e.printStackTrace();
}
}
public
static
void
closeSession()
throws
HibernateException {
Session session = threadLocal.get();
threadLocal.set(
null
);
if
(session !=
null
) {
session.close();
}
}
public
static
org.hibernate.SessionFactory getSessionFactory() {
return
sessionFactory;
}
public
static
void
setConfigFile(String configFile) {
HibernateSessionFactory.configFile = configFile;
sessionFactory =
null
;
}
public
static
Configuration getConfiguration() {
return
configuration;
}
}
相关文章推荐
- ServletFilter中管理Hibernate Session
- hibernate 之session 事务管理
- hibernate的二级缓存操作及session的管理方法及数据的批量处理
- Hibernate入门25 - Session 管理
- servlet学习笔记(3)-使用Java Servlet API 进行会话管理(对session的操作)
- Hibernate -- 配置c3p0连接池, 事务隔离级别, 管理session
- Spring使用OpenSessionInViewFilter解决Hibernate的lazy延时加载问题
- ThinkPHP写后台管理程序时如何合适合理地对Session进行验证
- 使用ThreadLocal模式管理Hibernate的Session
- spring对hibernate的session管理的配置
- spring管理hibernate4 transaction getCurrentSession为什么报错?
- 【知识整理】Hibernate-管理Session
- hibernate的事务管理和session对象的详解
- OpenSessionInViewFilter(Hibernate与Spring混合项目)
- Service层进行事务管理,Dao层获得session进行事务处理抛异常的情况
- Hibernate-struts 项目中Session的管理
- Hibernate——ThreadLocal模式下管理的Session会在事务提交后自动关闭
- 【Hibernate】Hibernate系列8之管理session
- spring_Spring+Hibernate_使用XML进行声明式事务管理
- hibernate 管理session对象的4种方式