无论是立即加载还是延迟加载必须要连接数据库的而在java中连接数据库是依赖javasqlConnection在hibernate中session就是Connection的一层高级封装一个session对应了一个Connection要实现延迟加载必须有session才行而且要进行延迟加载还必须保证是同一个session才行用另外一个session去延迟加载前一个session的代理对象是不行的大家都知道Connection是使用过后必须要进行关闭的那么我们如何保证一次http请求过程中一直都使用一个session呢即一个Connection呢而且还要保证http请求结束后正确的关闭
好现在我们知道了我们要解决的问题
如何保证http请求结束后正确的关闭session
如何保证http请求过程中一直使用同一个session
第一个问题很容易想到使用过滤器
view plaincopy to clipboardprint?
public void doFilter(ServletRequest request ServletResponse response
FilterChain filterChain) {
try {
filterChaindoFilter(request response);
} catch (IOException e) {
eprintStackTrace();
} catch (ServletException e) {
eprintStackTrace();
} finally {
try {
mitTransaction();
} catch (Exception e) {
HibernateUtilrollbackTransaction();
} finally {
HibernateUtilcloseSession();
}
}
}
public void doFilter(ServletRequest request ServletResponse response
FilterChain filterChain) {
try {
filterChaindoFilter(request response);
} catch (IOException e) {
eprintStackTrace();
} catch (ServletException e) {
eprintStackTrace();
} finally {
try {
mitTransaction();
} catch (Exception e) {
HibernateUtilrollbackTransaction();
} finally {
HibernateUtilcloseSession();
}
}
}要解决第二个问题我们必须先搞清楚http请求在java中是以什么样的机制实现的在java中一个请求就是一个线程像流行的web容器Tomcat等往往都是采用线程池机制的也就是说有n个线程在池子里面每当有http请求时随机从线程池中取出一个线程对象去处理请求实际上多次请求可能使用的是同一线程也可能不是这是随机的要保证整个请求中使用同一session最容易想到的就是把这个session绑定到线程上在java中使用ThreadLocal可以轻松绑定变量每个线程有一个自己的ThreadLocal这个ThreadLocal会随线程的销毁一起销毁既然是每个线程有一个那么多个线程间自然是不会有影响了所以把session绑定在ThreadLocal里面是最好的选择了
有关ThreadLocal的更多资料大家可以百度或者参考
最后我把相关的代码发出来
view plaincopy to clipboardprint?
import javasqlSQLException;
import orghibernateHibernateException;
import orghibernateSession;
import orghibernateSessionFactory;
import orghibernateTransaction;
import orghibernatecfgConfiguration;
import javasqlConnection;
import orgapachelogjLogger;
import javaioFile;
/**
*
* <p>
* Title:Hibernate工具类
* </p>
*
* <p>
* 利用ThreadLocal 绑定 Hibernate 的session
* </p>
*
* @author 孙钰佳
* @mail
* @version
*/
public class HibernateUtil {
/**
* Logerj的logger
*/
private static final Logger logger = LoggergetLogger(HibernateUtilclass);
/**
* 存储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();
nfigure(file);
sessionFactory = configbuildSessionFactory();
}
/**
* 获取当前线程绑定的session
*
* @return Session
* @throws HibernateException
*/
public static Session getSession() {
Session s = (Session) sessionThreadget();
if (s == null) {
s = sessionFactoryopenSession();
sessionThreadset(s);
} else {
Connection conn = nnection();
try {
if (conn == null || connisClosed()) {
try {
sclose();
} catch (HibernateException e) {
loggerwarn(close session error: + egetMessage() e);
}
s = sessionFactoryopenSession();
sessionThreadset(s);
}
} catch (SQLException e) {
throw new HibernateException(e);
}
}
return s;
}
/**
* 取得当前session的事务
*
* @return Transaction
*/
public static Transaction transaction() {
Transaction transaction = (Transaction) transactionThreadget();
if (transaction == null) {
transaction = getSession()beginTransaction();
transactionThreadset(transaction);
}
return transaction;
}
/**
* 提交当前session的事务
*/
public static void commitTransaction() {
Transaction transaction = (Transaction) transactionThreadget();
transactionThreadset(null);
if (transaction != null)
mit();
}
/**
* 回滚当前session的事务
*/
public static void rollbackTransaction() {
Transaction tx = (Transaction) transactionThreadget();
transactionThreadset(null);
if (tx != null)
txrollback();
}
/**
* 关闭当前线程使用的session
*/
public static void closeSession() {
Session session = (Session) sessionThreadget();
if (session != null) {
sessionclear();
sessionclose();
sessionThreadset(null);
}
}
}
import javasqlSQLException;
import orghibernateHibernateException;
import orghibernateSession;
import orghibernateSessionFactory;
import orghibernateTransaction;
import orghibernatecfgConfiguration;
import javasqlConnection;
import orgapachelogjLogger;
import javaioFile;
/**
*
* <p>
* Title:Hibernate工具类
* </p>
*
* <p>
* 利用ThreadLocal 绑定 Hibernate 的session
* </p>
*
* @author 孙钰佳
* @mail
* @version
*/
public class HibernateUtil {
/**
* Logerj的logger
*/
private static final Logger logger = LoggergetLogger(HibernateUtilclass);
/**
* 存储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();
nfigure(file);
sessionFactory = configbuildSessionFactory();
}
/**
* 获取当前线程绑定的session
*
* @return Session
* @throws HibernateException
*/
public static Session getSession() {
Session s = (Session) sessionThreadget();
if (s == null) {
s = sessionFactoryopenSession();
sessionThreadset(s);
} else {
Connection conn = nnection();
try {
if (conn == null || connisClosed()) {
try {
sclose();
} catch (HibernateException e) {
loggerwarn(close session error: + egetMessage() e);
}
s = sessionFactoryopenSession();
sessionThreadset(s);
}
} catch (SQLException e) {
throw new HibernateException(e);
}
}
return s;
}
/**
* 取得当前session的事务
*
* @return Transaction
*/
public static Transaction transaction() {
Transaction transaction = (Transaction) transactionThreadget();
if (transaction == null) {
transaction = getSession()beginTransaction();
transactionThreadset(transaction);
}
return transaction;
}
/**
* 提交当前session的事务
*/
public static void commitTransaction() {
Transaction transaction = (Transaction) transactionThreadget();
transactionThreadset(null);
if (transaction != null)
mit();
}
/**
* 回滚当前session的事务
*/
public static void rollbackTransaction() {
Transaction tx = (Transaction) transactionThreadget();
transactionThreadset(null);
if (tx != null)
txrollback();
}
/**
* 关闭当前线程使用的session
*/
public static void closeSession() {
Session session = (Session) sessionThreadget();
if (session != null) {
sessionclear();
sessionclose();
sessionThreadset(null);
}
}
}
下面是一个调用的例子: view plaincopy to clipboardprint?
public static void main(String[] args) throws Exception {
HibernateUtilinitSessionFactory(new File(TestclassgetClassLoader()
getResource(hibernatecfgxml)getFile()));
Session session = HibernateUtilgetSession();
HibernateUtiltransaction();
User u = new User();
usetName(test);
sessionsave(u);
mitTransaction();
HibernateUtilcloseSession();
}