无论是立即加载还是延迟加载必须要连接数据库的,而在java中连接数据库是依赖java.sql.Connection,在hibernate中session就是Connection的一层高级封装,一个session对应了一个Connection,要实现延迟加载必须有session才行.而且要进行延迟加载还必须保证是同一个session才行,用另外一个session去延迟加载前一个session的代理对象是不行的.大家都知道Connection是使用过后必须要进行关闭的,那么我们如何保证一次http请求过程中,一直都使用一个session呢,即一个Connection呢.而且还要保证http请求结束后正确的关闭.
好,现在我们知道了我们要解决的问题
1.如何保证http请求结束后正确的关闭session
2.如何保证http请求过程中一直使用同一个session
第一个问题很容易想到,使用过滤器
view plaincopy to clipboardprint?
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) {
try {
filterChain.doFilter(request, response);
} catch (IOException e) {
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
} finally {
try {
HibernateUtil.commitTransaction();
} catch (Exception e) {
HibernateUtil.rollbackTransaction();
} finally {
HibernateUtil.closeSession();
}
}
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) {
try {
filterChain.doFilter(request, response);
} catch (IOException e) {
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
} finally {
try {
HibernateUtil.commitTransaction();
} catch (Exception e) {
HibernateUtil.rollbackTransaction();
} finally {
HibernateUtil.closeSession();
}
}
}要解决第二个问题我们必须先搞清楚,http请求在java中是以什么样的机制实现的,在java中一个请求就是一个线程,像流行的web容器Tomcat等,往往都是采用线程池机制的也就是说有n个线程在池子里面,每当有http请求时,随机从线程池中取出一个线程对象去处理请求,实际上多次请求可能使用的是同一线程也可能不是,这是随机的.要保证整个请求中使用同一session最容易想到的就是把这个session绑定到线程上,在java中使用ThreadLocal可以轻松绑定变量,每个线程有一个自己的ThreadLocal,这个ThreadLocal会随线程的销毁一起销毁,既然是每个线程有一个那么多个线程间自然是不会有影响了,所以把session绑定在ThreadLocal里面是最好的选择了,
有关ThreadLocal的更多资料,大家可以百度或者参考
http://www-128.ibm.com/developerworks/cn/java/j-threads/index3.html
http://www.blogjava.net/jspark/archive/2006/08/01/61165.html
最后我把相关的代码发出来
view plaincopy to clipboardprint?
import java.sql.SQLException;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import java.sql.Connection;
import org.apache.log4j.Logger;
import java.io.File;
/**
*
* <p>
* Title:Hibernate工具类
* </p>
*
* <p>
* 利用ThreadLocal 绑定 Hibernate 的session
* </p>
*
* @author 孙钰佳
* @mail sunyujia@yahoo.cn
* @version 1.0
*/
public class HibernateUtil {
/**
* Loger4j的logger
*/
private static final Logger logger = Logger.getLogger(HibernateUtil.class);
/**
* 存储hibernate session的ThreadLocal
*/
private static final ThreadLocal sessionThread = new ThreadLocal();
/**
* 存储事务的ThreadLocal
*/
private static final ThreadLocal transactionThread = new ThreadLocal();
/**
* Hibernate 的 Session工厂
*/
private static SessionFactory sessionFactory = null;
/**
* 初始化SessionFactory
*
* @param file
* Hibernate配置文件
*/
public static void initSessionFactory(File file) {
Configuration config = new Configuration();
config.configure(file);
sessionFactory = config.buildSessionFactory();
}
/**
* 获取当前线程绑定的session
*
* @return Session
* @throws HibernateException
*/
public static Session getSession() {
Session s = (Session) sessionThread.get();
if (s == null) {
s = sessionFactory.openSession();
sessionThread.set(s);
} else {
Connection conn = s.connection();
try {
相关专题
- Hibernate原理与配置 (384篇文章)
- Hibernate相关文章 (384篇文章)
- Struts 2, spring 2, hibernate 的整合 (403次浏览)
- Java远程通讯的6种可选技术及原理 (279次浏览)
- struts2 + spring + hibernate 实现CRUD (217次浏览)
- Spring 与 Log4J 进行动态日志配置切换 (182次浏览)
- 初学者对Hibernate的学习方法 (168次浏览)
- Hibernate的映射关联关系 (154次浏览)
- Spring与struts整合开发实例(一) (111次浏览)
- Java调用SQL Server的存储过程详解 (109次浏览)
- MyEclipse搞定hibernate的web应用 (104次浏览)
- 多动鼠标少动脑,Java报表工具的简约之美 (92次浏览)



