posts - 3, comments - 13, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理
在暑假里看了“Refactoring to Patterns”这本书,觉得很不错。里边讲到了很多在优化编码时可以用到的设计模式以及它们的用法。
    我在编程时,一般都是用Spring作为中间层管理资源,而用Hibernate作为ORM。用过Spring的人都知道Spring对Hibernate的支持方法较多,我常用的是直接继承HibernateDaoSupport类。我们先来看一个类图:
Dao Class Diagram
在是我在应用中常用到的类结构。因为对于一个域模型来说,最基本的就是CRUD操作,所以将其放在Dao接口中,但是对于每个不同的域模型又有其特有的方法,则将其放在域模型对应的接口(SomeSpecificDao)中。
    这样,对于最基本的CRUD操作就可以只需在BaseHibernateDao中实现,这一点利用了Template Method设计模式。对于create(), delete()和modify()三个方法都可以简单实现,即调用HibernateTemplate中相应的方法。对于findAll和findById,则可以借住Java的反射来实现。这里如果要利用反射且达到通用的目的,就需要将所有的域模型放在一个包中,并且有相同的命名规则,比如说如果域模型叫做User,那么相应的Dao应该以User开头,不过这也是常用的方法。下面给出一小段代码
/**
     * A convenience and generic method for retrieving all models from the database
         * @throws DataAccessException
     */

    
public List findAll() throws DataAccessException {
        
// TODO Auto-generated method stub
        List models = new ArrayList();
        
try {
            models 
= getHibernateTemplate().loadAll(
                    Class.forName(getClass().getName().replaceAll(
                            
"HibernateDao""").replaceAll("dao.hibernate",
                            
"model")));
        }
 catch (ClassNotFoundException exception) {
            
// TODO Auto-generated catch block
            exception.printStackTrace();
        }

        
return models;
    }
    以上给出的是findAll的实现,findById也是一样。这样一来,就无需再在子类中重复编写CRUD算法的实现了。
     再有就是在编写子类Dao中特有的find方法,因为利用HibernateTemplate中的execute方法来实现,所以可以在BaseHibernateDao这个父类中编写一个protected的方法,以便子类Dao调用,这个方法中包含了调用HibernateTemplate中execute方法的代码:
/**
     * Covenience method for retrieving objects by HQL
     
*/

    
protected Query find(final String query)
            
throws DataAccessException {
        Query aQuery 
= (Query) getHibernateTemplate().execute(
                
new HibernateCallback() {
                    
public Object doInHibernate(Session session) {
                        
return session.createQuery(query);
                    }

                }
);
        
return aQuery;
    }
     这样在子类Dao中就可以直接调用该find方法来实现,而不必每次都编写繁琐的execute方法。
     以上的方法我都做过测试,在实现和应用中没有问题。在效率上可能会比在子类中实现要差一点,因为find*方法中用到了Java的反射,对效率会一定的影响,这是缺点之一。如果有哪位有更好的办法,请在评论中写出,欢迎大家进行评判,谢谢……

评论

# re: 关于Spring中利用Hibernate作为DAO的简化  回复  更多评论   

2008-01-11 09:17 by yf
冒昧问一下,我用.hibernateSynchronizer3生成的DAO中为什么没有findById(),findByExample()等函数,只有findAll()啊?谢谢

# re: 关于Spring中利用Hibernate作为DAO的简化  回复  更多评论   

2008-01-11 09:18 by yf
MSN:yellow.flying@hotmail.com有时间请教一下

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


网站导航: