Goingmm

  BlogJava :: 首页 :: 新随笔 ::  :: 聚合  :: 管理 ::
  82 随笔 :: 15 文章 :: 452 评论 :: 0 Trackbacks

    
     周末和 MIKE 吃饭的时候,他询问,上次提说的问题,什么时候能写出来。“对SessionTransaction的处理,最好单独实现一个模板类来统一做”

 

温故 居于常规的HibernateDAO代码。例子做一个Create操作

 1public void createPerson() {
 2        Session session = null;
 3        Transaction tran = null;
 4        try {
 5            // Obtain Session
 6            Configuration config = new Configuration()
 7                    .configure();
 8            SessionFactory sessionFactory = config.buildSessionFactory();
 9            session = sessionFactory.openSession();
10
11            // Obtain Transaction
12            tran = session.beginTransaction();
13
14            // Obtain Person
15            Person person = new Person();
16            person.setPersonName("IBM");
17            person.setPersonEmail("goingmm@gmail.com");
18            person.setPersonSex("M");
19            // Create Person
20            session.save(person);
21            session.flush();
22            tran.commit(); // 这步安全执行后,Person真正写入数据库
23        }
 catch (HibernateException e) {
24            e.printStackTrace();
25            if (tran != null{
26                try {
27                    tran.rollback();
28                }
 catch (HibernateException ex) {
29                    ex.printStackTrace();
30                }

31            }

32        }
 finally {
33            if (session != null)
34                session.close();
35        }

36    }

37


     这段代码怎么样? 假如这样的代码会出现在你的每一个DAO的每一个方法里面(除了SessionFactory建议写成一个方法,因为你只需要一个实例)你能接受吗?只说try catch 就够你写的。

如果代码在每个地方都出现。那么我想就可以抽离出来。做成一个模板。具体该怎么做呢?今天我打算谈三种比较成熟的做法。

      采用Spring提供的模板功能

      自己实现一个功能相当的模板

      其他可借鉴的实现

 

采用Spring提供的模板功能

看代码:

         

 1     public class PersonHibernateDao extends HibernateDaoSupport implements IPersonDao{
 2
 3         public void saveUser(Person person){
 4
 5              getHibernateTemplate().saveOrUpdate(person);
 6
 7         }

 8
 9     }

10

 

     比起上面的代码,现在简单多了吧?其实该做的事情都做了,只不过是被Spring封装起来了。大致跟踪一下SpringSourceCode的实现。

1)   在抽象类HibernateDaoSupport中有一个方法getHibernateTemplate()。通过getHibernateTemplate()得到一个HibernateTemplate对象。

2)   HibernateDaoSupport中有两个方法。通过他们来的到这个 HibernateTemplate对象

 1public final void setSessionFactory(SessionFactory sessionFactory) {
 2
 3  this.hibernateTemplate = createHibernateTemplate(sessionFactory);
 4
 5}

 6
 7protected HibernateTemplate createHibernateTemplate(SessionFactory sessionFactory) {
 8
 9     return new HibernateTemplate(sessionFactory);
10
11}

12


3)   找到saveOrUpdate()方法

 1public void saveOrUpdate(final Object entity) throws DataAccessException {
 2   execute(new HibernateCallback() // call execute() 
 3// 这里使用了匿名内部类 来实现doInHibernate()
 4     public Object doInHibernate(Session session) throws HibernateException {
 5               checkWriteOperationAllowed(session);
 6               session.saveOrUpdate(entity);
 7               return null;
 8          }

 9     }
true);
10}

11

4)   核心的实现就在HibernateTemplate里面。篇幅原因,我就不Copy全部的代码了


1public Object execute(HibernateCallback action, boolean exposeNativeSession) throws DataAccessException {
2
3}

4


这里,帮你做了SessionTransaction的封装。让你可以免去烦琐无谓的try catch finally 和相关操作。在Spring中基本上采用容器处理事务。这样在事务的处理上也达到了统一性。    

    到这里,感觉还不错吧? 要是你没有打算使用Spring呢?这种优势不就没有了吗?那到未必,既然都有得“抄袭”拉!就自己弄一个吧!

 

自己实现一个功能相当的模板

不容易描述清楚,就用简单的代码来说明吧。

 

 1package com.goingmm.test;
 2import org.hibernate.HibernateException;
 3import org.hibernate.Session;
 4import org.hibernate.SessionFactory;
 5import org.hibernate.Transaction;
 6import org.hibernate.cfg.Configuration;
 7// HibernateTemplate 来集中处理 Session和Transaction
 8
 9public class HibernateTemplate {
10     public static SessionFactory sessionFactory = null;
11public void perform(HibernateCallback callback) {
12         Session session = null;
13         Transaction tx = null;
14         try {
15              if (sessionFactory != null)
16                   session = sessionFactory.openSession();
17              else
18                   session = initSessionFactory().openSession();
19              tx = session.beginTransaction();
20// 把对象纳入Hibernate管理是在execute里面实现的
21              callback.execute(session);
22              session.flush();
23              tx.commit();
24         }
 catch (HibernateException e) {
25              try {
26                   tx.rollback();
27              }
 catch (Throwable t) {
28              }

29              throw new RuntimeException(e);
30         }
 finally {
31              try {
32                   if(session != null)
33session.close();
34              }
 catch (HibernateException ex) {
35                   throw new RuntimeException(ex);
36              }

37         }

38     }

39// 建议用一个Servlet,在应用开始的时候Call一次 来初始化SessionFactory
40     public static SessionFactory initSessionFactory() {
41         Configuration config = new Configuration().configure();
42         sessionFactory = config.buildSessionFactory();
43         return sessionFactory;
44     }

45}

46



 

1package com.goingmm.test;
2import org.hibernate.HibernateException;
3import org.hibernate.Session;
4public interface HibernateCallback {
5     void execute(Session session) throws HibernateException;
6}

7
8 
9

 

 1package com.goingmm.test;
 2import org.hibernate.HibernateException;
 3import org.hibernate.Session;
 4
 5public class PersonHibernateDao implements IDAO{
 6public void create(final Object person) {
 7// 这里使用了匿名内部类 来实现execute
 8new HibernateTemplate().perform(new HibernateCallback(){
 9              public void execute(Session session) throws HibernateException {
10//标题不是说Session要撤离吗?    这里撤离了,就等于没有使用Hibernate 呵呵!
11session.save(person); 
12         }

13     }
);
14     }

15}

16

 

 1package com.goingmm.test;
 2import com.goingmm.bean.Person;
 3public class UseHibernateTemplateTest{
 4     public static void main(String[] args) {
 5         IDAO dao = new PersonHibernateDao();
 6         Person person = new Person();
 7         person.setPersonName("IBM");
 8         person.setPersonEmai("goingmm@gmail.com");
 9         person.setPersonSex("M");
10         dao.create(person);
11     }

12}

13


     上面的DAO实现还有代码风格都不推荐大家学习。实现一个优秀的DAO框架没这么简单。这种做法我没有在真实项目中检验过,不确定,会不会有其他问题。因为这里我只是为了简单的表述HibernateTemplate思想的实现。只要理解了这种思想,相信你能写出更好更完美的实现。如果有更好的主意或者建议请Email告诉我。

 

其他可借鉴的实现

     《深入浅出Hibernate》采用hibernatesynchronizer生成基础代码的方式,架构自己的持久层。作者自己实现了一个相似功能的HibernateTemplateHibernateCallback接口。有兴趣的话可以去研究一下。

     这种能直接生成基础代码的方式很不错。比起Spring我还是觉得麻烦了很多。而且我也还没时间去全面玩这个插件(据说,有提供一些成熟的模板方式生成,我只玩过默认的生成方式)。

    

2005-12-6 SCSCHINA New Office


posted on 2005-12-07 13:55 Goingmm 阅读(1682) 评论(11)  编辑  收藏 所属分类: Reading Note

评论

# re: Session和Transaction安全撤离现场 2005-12-07 14:37 sanmans
shafa  回复  更多评论
  

# re: Session和Transaction安全撤离现场 2005-12-07 15:17 sofaer
sofa  回复  更多评论
  

# re: Session和Transaction安全撤离现场 2005-12-07 15:20 sofaer
原来不是沙发了哈,你最近在看《深入浅出Hibernate》吗?  回复  更多评论
  

# re: Session和Transaction安全撤离现场 2005-12-07 16:12 sanmans
public class PersonHibernateDao implements IDAO{}
IDAO舍不得拿来看索!  回复  更多评论
  

# re: Session和Transaction安全撤离现场 2005-12-08 16:02 todogoingmm
SORRY Sanmans... 没什么神秘的,忘记了贴出来
public interface IDAO {
public void create(final Object obj);
}
我只是随便放的一个方法,关于DAO的结构,勿模仿
最近在看《深入浅出Hibernate》?
没有,最近想看看书,但是总静不下来
上次去北京前看了这本书的部分,内容和作者发布的免费文档差不多  回复  更多评论
  

# re: Session和Transaction安全撤离现场 2005-12-09 16:14 jigsaw
am wondering what's the core value of web app...
is there any experience/knowledge can make you irreplaceable?
none!
anyone can read through the docs/books and get familiar with those frameworks after a few real projects -- all these wont take
more than 2 yrs
and after reading piles of *best practice*, *tips & traps*, etc., all you can do is to follow those styles, to obey those rules....it has nothing to do with innovation
err...so what tech can make you unique? hmmm...pls tell me if you figure it out someday....=P

anyway, u did a good job of inroduction to template pattern in persistance. what make sence is that you did it in ur own way.  回复  更多评论
  

# re: Session和Transaction安全撤离现场 2005-12-12 14:06 9527
呵呵,典型的先抑后扬。我有个朋友在研究非冯诺依曼计算机,XQL有没有兴趣参加科研啊?瓦卡卡。。。  回复  更多评论
  

# re: Session和Transaction安全撤离现场 2005-12-12 14:39 todogoingmm
无意间了解了,眼下不被大众看好的ERP市场.
http://tech.sina.com.cn/it/2005-11-16/1120767283.shtml

不知道“新世界”有没有实力彻底垄断ERP市场。说不清楚这种趋势下ERP的未来是混乱还是规范。
当然,引用ERP只是从一个侧面去看待问题。做J2EE将近两年时间了。也没有太多时间去考虑行业,技术的未来。本着自己仅有的兴趣在“混饭吃”。J2EE的发展趋势必然是一天比一天规范。有时候傻傻的想,以后做软件可能就像写WORD文档。
3G 即将到来,离我们最近的分水岭-J2ME。暧昧的在诱惑着我。有个朋友说得有道理,在中国想发财得赚小钱,赚13亿人每人一块。这辈子就够了。

人的本能。求变总是在求存之后。
-- J2EE小资  回复  更多评论
  

# re: Session和Transaction安全撤离现场 2005-12-12 14:43 9527
兄弟们,拼命挣钱吧,不过一定要开心哦。  回复  更多评论
  

# re: Session和Transaction安全撤离现场 2005-12-13 15:29 jigsaw
j2me? trust me, it's rubbish  回复  更多评论
  

# re: Session和Transaction安全撤离现场 2005-12-13 15:49 jigsaw
3G好像是不错。。。不过非冯诺伊曼那个。。。等下辈子吧。。。  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: