最近做一个公司项目的Demo,使用技术为jsp+dwr+hibernate,因为该Demo中所用的表多,有一对一,一对多和多对一的关系,所以利用hibernate的延迟加载(lazy="true")对性能的提高相当重要,但随之带来的session管理更为重要,弄不好常出现延迟加载异常,在这里我利用了Filter 来处理session的close的,相关代码如下:
1.HibernateSessionFactory.java(Eclipse自动生成,通过ThreadLocal 将session的非线程安全变成安全)
- import org.apache.log4j.Logger;
- import org.hibernate.HibernateException;
- import org.hibernate.Query;
- import org.hibernate.Session;
- import org.hibernate.cfg.Configuration;
- public class HibernateSessionFactory {
- private static final Logger log = Logger.getLogger(SessionFactory.class) ;
- private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
- private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
- private static Configuration configuration = new Configuration();
- private static org.hibernate.SessionFactory sessionFactory;
- private static String configFile = CONFIG_FILE_LOCATION;
- static {
- try {
- configuration.configure(configFile);
- sessionFactory = configuration.buildSessionFactory();
- } catch (Exception e) {
- log.error(" error creating sessionFactory") ;
- e.printStackTrace();
- }
- }
- public HibernateSessionFactory() {
- }
- public static Session getSession() throws HibernateException {
- log.info("getSession is run") ;
- Session session = (Session) threadLocal.get();
- if (session == null || !session.isOpen()) {
- log.info("SessionFactory.getSession() session is null or close") ;
- if (sessionFactory == null) {
- log.info("SessionFactory.getSession() rebuildSessionFactory() is running") ;
- rebuildSessionFactory();
- }
- session = (sessionFactory != null) ? sessionFactory.openSession(): null;
- threadLocal.set(session);
- }
- return session;
- }
- public static void rebuildSessionFactory() {
- log.info("rebuildSessionFactory is run") ;
- try {
- configuration.configure(configFile);
- sessionFactory = configuration.buildSessionFactory();
- } catch (Exception e) {
- log.error("erro creating sessionFactory") ;
- e.printStackTrace();
- }
- }
- public static void closeSession() throws HibernateException {
- log.info("closeSession is run") ;
- Session session = (Session) threadLocal.get();
- threadLocal.set(null);
- if (session != null) {
- log.info("SessionFactory.closeSession() session is not null") ;
- if(!session.isOpen()){
- System.out.println("该 session 已经关闭") ;
- }
- session.close();
- }
- }
- public static org.hibernate.SessionFactory getSessionFactory() {
- return sessionFactory;
- }
- public static void setConfigFile(String configFile) {
- SessionFactory.configFile = configFile;
- sessionFactory = null;
- }
- public static Configuration getConfiguration() {
- return configuration;
- }
- }
import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
public class HibernateSessionFactory {
private static final Logger log = Logger.getLogger(SessionFactory.class) ;
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static Configuration configuration = new Configuration();
private static org.hibernate.SessionFactory sessionFactory;
private static String configFile = CONFIG_FILE_LOCATION;
static {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
log.error(" error creating sessionFactory") ;
e.printStackTrace();
}
}
public HibernateSessionFactory() {
}
public static Session getSession() throws HibernateException {
log.info("getSession is run") ;
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
log.info("SessionFactory.getSession() session is null or close") ;
if (sessionFactory == null) {
log.info("SessionFactory.getSession() rebuildSessionFactory() is running") ;
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession(): null;
threadLocal.set(session);
}
return session;
}
public static void rebuildSessionFactory() {
log.info("rebuildSessionFactory is run") ;
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
log.error("erro creating sessionFactory") ;
e.printStackTrace();
}
}
public static void closeSession() throws HibernateException {
log.info("closeSession is run") ;
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
log.info("SessionFactory.closeSession() session is not null") ;
if(!session.isOpen()){
System.out.println("该 session 已经关闭") ;
}
session.close();
}
}
public static org.hibernate.SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void setConfigFile(String configFile) {
SessionFactory.configFile = configFile;
sessionFactory = null;
}
public static Configuration getConfiguration() {
return configuration;
}
}
HibernateSessioniFactory主要负责session的开和关。
2.HibernateSessionFilter(要编写的过滤器,主要处理session的关闭)
- 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.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import com.ad.session.HibernateSessionFactory;
- public class HibernateSessionFilter implements Filter {
- private static final Log log = LogFactory.getLog(HibernateSessionFilter.class);
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- System.out.println("HibernateSessionFilter is end") ;
- }
- @Override
- public void doFilter(ServletRequest arg0, ServletResponse arg1,
- FilterChain chain) throws IOException, ServletException {
- log.debug("HibernateSessionFilter start");
- try{
- //request 之前要处理的代码
- chain.doFilter(arg0, arg1);
- //response之后要要处理的代码
- }catch (Exception e) {
- e.printStackTrace();
- } finally{
- HibernateSessionFactory.closeSession();
- }
- }
- @Override
- public void destroy() {
- System.out.println("HibernateSessionFilter is start") ;
- }
- }
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.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.ad.session.HibernateSessionFactory;
public class HibernateSessionFilter implements Filter {
private static final Log log = LogFactory.getLog(HibernateSessionFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("HibernateSessionFilter is end") ;
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain chain) throws IOException, ServletException {
log.debug("HibernateSessionFilter start");
try{
//request 之前要处理的代码
chain.doFilter(arg0, arg1);
//response之后要要处理的代码
}catch (Exception e) {
e.printStackTrace();
} finally{
HibernateSessionFactory.closeSession();
}
}
@Override
public void destroy() {
System.out.println("HibernateSessionFilter is start") ;
}
}
该过滤器只处理session的关闭,似乎有点浪费了,在这也可以加上字符集的处理。
Filter运行原理(个人认为,有误请多指教):首先建立一个过滤类,需继承Filter接口,必须实现三个方法:
init:服务器启动时运行该方法,运行期间不执行;
doFilter:运行期间执行,其作用是request之前要做那些工作,response之后(即服务器将内容全部发回View层后)
要做那些工作。每次访问服务器都会执行doFilter方法
destroy:服务器终止时运行。
3. 在web.xml中的配置如下:
- <filter>
- <filter-name>hibernateSession</filter-name>
- <filter-class>
- com.c35.ad.filter.HibernateSessionFilter
- </filter-class>
- </filter>
- <filter-mapping>
- <filter-name>hibernateSession</filter-name>
- <url-pattern>/*</url-pattern><!-- 过滤所有发回服务器的请求-->
- </filter-mapping>
<filter> <filter-name>hibernateSession</filter-name> <filter-class> com.c35.ad.filter.HibernateSessionFilter </filter-class> </filter> <filter-mapping> <filter-name>hibernateSession</filter-name> <url-pattern>/*</url-pattern><!-- 过滤所有发回服务器的请求--> </filter-mapping>
4.dao(demo中的UserDao)
- public class UserDao implements BaseDao {
- private static final Logger log = Logger.getLogger(UserDao.class);
- private Session session ;
- public UserDao(){
- log.info("UserDao construct is running") ;
- session = SessionFactory.getSession() ;
- }
- @Override
- public boolean save(Object o) {
- log.info("UserDao save is running ");
- boolean flag = false ;
- Transaction tran = null;
- try {
- tran = session.beginTransaction();
- session.save(o);
- tran.commit();
- flag = true ;
- } catch (Exception e) {
- log.error("error save user");
- flag = false ;
- if (tran != null) {
- try {
- tran.rollback();
- } catch (HibernateException e1) {
- log.error("save Transaction rollback is error "+e1.getMessage()) ;
- }
- }
- e.printStackTrace();
- }finally{
- //session.close() ;//这里就不需要在关闭session直接交给filter来处理
- }
- return flag ;
- }
- }
public class UserDao implements BaseDao {
private static final Logger log = Logger.getLogger(UserDao.class);
private Session session ;
public UserDao(){
log.info("UserDao construct is running") ;
session = SessionFactory.getSession() ;
}
@Override
public boolean save(Object o) {
log.info("UserDao save is running ");
boolean flag = false ;
Transaction tran = null;
try {
tran = session.beginTransaction();
session.save(o);
tran.commit();
flag = true ;
} catch (Exception e) {
log.error("error save user");
flag = false ;
if (tran != null) {
try {
tran.rollback();
} catch (HibernateException e1) {
log.error("save Transaction rollback is error "+e1.getMessage()) ;
}
}
e.printStackTrace();
}finally{
//session.close() ;//这里就不需要在关闭session直接交给filter来处理
}
return flag ;
}
}
以上是本人的学习总结,有误之处请多多指教,希望对刚学hibernate的同志们有所帮助。