|
该帖已经被评为精华帖
|
|
|---|---|
| 作者 | 正文 |
|
时间:2004-03-06
一、建立一个HIBERNATE的初始化类,注意类中STATIC变量的应用。
package com.yours.hibernate_frame.datamodel; import net.sf.hibernate.HibernateException; import net.sf.hibernate.Session; import net.sf.hibernate.SessionFactory; import net.sf.hibernate.cfg.Configuration; public class HibernateUtil { private static final SessionFactory sessionFactory; static { try { sessionFactory = new Configuration().configure().buildSessionFactory(); } catch (HibernateException ex) { throw new RuntimeException( "Exception building SessionFactory: " + ex.getMessage(),ex); } } public static final ThreadLocal session = new ThreadLocal(); public static Session currentSession() throws HibernateException { Session s = (Session) session.get(); // Open a new Session, if this Thread has none yet if (s == null) { s = sessionFactory.openSession(); session.set(s); } return s; } public static void closeSession() throws HibernateException { Session s = (Session) session.get(); session.set(null); if (s != null) s.close(); } } 二、在DAO中 HibernateUtil.currentSession()被多次调用,但是由于HibernateUtil使用了静态(static)块,所以sessionFactory只会在该类载入内存中时调用一次,所以不会存在多次调用的情况,也就不会占用太多的资源。在TOMCAT等JSP容器中,sessionFactory是被多用户共享,还是每个用户使用一个sessionFactory,这点我不是很清楚,希望有人能提自已的看法。 JAVA类变量的传递,本质是传递内存地址(原始变量除外),由于HibernateUtil中的session是静态变量,所以可以直接在DAO中调用HibernateUtil.closeSession()关闭,因此在DAO中增加如下一个方法,用来代替在Filter中自动关闭SESSION,这种做法有点象C++的析构函数。 public void closeSession() throws HibernateException { HibernateUtil.closeSession(); } package com.yours.admin.dao; import com.yours.admin.jdo.*; import com.yours.hibernate_frame.datamodel.HibernateUtil; import net.sf.hibernate.HibernateException; import net.sf.hibernate.Transaction; import net.sf.hibernate.Session; /** * <p>Title:USER </p> * <p>Description: </p> * <p>Copyright: Copyright (c) 2004</p> * <p>Company: </p> * @author 段洪杰 * @version 1.0 */ public class UserDAOImpl implements UserDAO { public UserDAOImpl() { } /** * 建立用户 * @param user User * @throws HibernateException */ public void setUser(User user) throws HibernateException{ Session s = HibernateUtil.currentSession(); Transaction tx = null; try{ tx = s.beginTransaction(); s.save(user); tx.commit(); }catch(HibernateException he){ if ( tx!=null ){ tx.rollback(); } throw he; } s.flush(); } /** * 删除用户 * @param user User * @throws HibernateException */ public void removeUser(User user) throws HibernateException { Session s = HibernateUtil.currentSession(); Transaction tx = null; try{ tx = s.beginTransaction(); s.delete(user); tx.commit(); }catch(HibernateException he){ if ( tx!=null ){ tx.rollback(); } throw he; } s.flush(); } /** * 通过Id取得用户 * @param id String * @throws HibernateException * @return User */ public User getUserById(String id) throws HibernateException { User user = null; Session s = HibernateUtil.currentSession(); Transaction tx = null; try{ tx = s.beginTransaction(); user = (User) s.load( User.class, id ); tx.commit(); }catch(HibernateException he){ if ( tx!=null ){ tx.rollback(); } throw he; } s.flush(); return user; } /** * 关闭Hibernate的session */ public void closeSession() throws HibernateException { HibernateUtil.closeSession(); } } ----- 希望大家对此贴进行讨论,批评的意见也非常欢迎! 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
时间:2004-03-07
务必给点意见,痛批或支持都可以!
|
|
| 返回顶楼 | |
|
时间:2004-03-07
这不就是Hibernate文档里提到那个session locator模式吗?你不妨先说说看,你觉得这么做的好处在哪里?我已经发现了一些问题,不过先听听你自己的想法吧。
|
|
| 返回顶楼 | |
|
时间:2004-03-07
gigix 写道 这不就是Hibernate文档里提到那个session locator模式吗?你不妨先说说看,你觉得这么做的好处在哪里?我已经发现了一些问题,不过先听听你自己的想法吧。
我觉在在DAO中关闭SESSION有些勉强.如果多个DAO共一个SESSION,又违反了SESSION用过后要极时关闭的原则. 不把sessionFactory绑定在jndi上,分步调程序时要方便的多. |
|
| 返回顶楼 | |
|
时间:2004-03-07
其实多个DAO共用一个session并不会违反session用过后及时关闭的原则。你可以选择在调用DAO的地方关闭session。比如在一个SLSB中,
dao1.dosomething(); HibernateSession.closeSession(); 再举个例子 dao1.dosomething(); dao2.dosomething(); HibernateSession.closeSession(); 虽然没有在每个dao方法中关闭session,但也不能称作不及时,因为在第一个方法调用后你还要用到session。所以没有必要太在乎session是否被及时关闭,这不会带来多少性能上的损失。 再比如,在两个dao中加一些语句,除非是很巨大的计算量,不然时间不会很长,至少比访问数据库的时间要小。如果是很大量的计算就应该把这部分分离出去。 |
|
| 返回顶楼 | |
|
时间:2004-03-07
sayor SAP的说法很有道理, 我的想法也基本跟他的相似.不过
dao1.dosomething(); dao2.dosomething(); HibernateSession.closeSession(); 的做法不太符合一般人的习惯,一般是有打开才有关闭. 所以不如再加一个数据抽象层改为: dataMode.begin(); dao1.dosomething(); dao2.dosomething(); dataMode.end(); 把HibernateSession作为一个单例封装到dataMode中去. 如果以后不再用hibernate了.以后调用DAO时还可以象上面一样的使用.但是由于HibernateSession用的是静态变量,把HibernateSession作为一个单例封装到dataMode中去,又有画蛇添足的感觉. |
|
| 返回顶楼 | |
|
时间:2004-03-07
我的做法是在business service组件上加一个拦截器,每调用一个business service方法之后自动关闭session,这样业务代码就完全不必关系session的开闭、事务的提交/回滚。你觉得这个做法怎么样呢?
|
|
| 返回顶楼 | |
|
时间:2004-03-08
gigix 写道 我的做法是在business service组件上加一个拦截器,每调用一个business service方法之后自动关闭session,这样业务代码就完全不必关系session的开闭、事务的提交/回滚。你觉得这个做法怎么样呢?
AOP(面向方面编程)技术,似乎能很好的解决此类问题. 自已编写组件拦截器,好象太麻烦. |
|
| 返回顶楼 | |
|
时间:2004-03-09
dhj1 写道 gigix 写道 我的做法是在business service组件上加一个拦截器,每调用一个business service方法之后自动关闭session,这样业务代码就完全不必关系session的开闭、事务的提交/回滚。你觉得这个做法怎么样呢?
AOP(面向方面编程)技术,似乎能很好的解决此类问题. 自已编写组件拦截器,好象太麻烦. 我说的就是AOP的拦截器,基于AOP-Alliance API,用Spring实现。 |
|
| 返回顶楼 | |
|
时间:2004-03-09
用Spring的HibernateTransactionManager类吧,它能够让你写出更漂亮的代码
|
|
| 返回顶楼 | |









