现在的位置: 首页 > 综合 > 正文

spring提供的HibernateTemplate()回调函数 为什么要用?

2014年09月29日 ⁄ 综合 ⁄ 共 2320字 ⁄ 字号 评论关闭

当spring提供的HibernateTemplate()没有提供所需要的功能时,可以用回调函数实现相关功能。

     不提倡用getSession()来获得session来实现,因为这样拿到的session是hibernate最原始的session,不享有Spring提供的模板支持 

在DAO类中可以使用下面的方法取得session:

 

  final String queryString = "from Fourm";                 //必须定义final类型
   List l= getHibernateTemplate().executeFind(new HibernateCallback(){
    public Object doInHibernate ( Session session ) throws HibernateException, SQLException {
                    Query query = session.createQuery ( queryString ) ;
                    query.setFirstResult ( 0 ) ;
                    query.setMaxResults ( 10 ) ;
                    List list = query.list ( ) ;
                    return list ;
          }


动态回调函数、匿名内部类和spring中的excute方法

 

    公司目前采用了spring框架来构建和管理整个web项目。对于持久层的处理,使用了由spring框架提供的对hibernate3的封装。这样做无非是为了使用spring提供的对事务的统一管理。当我们用到由spring所封装的hibernate的时候一定会用到一个类:HibernateTemplate.这是一个对持久层处理封装的非常完整的类,包括对session的管理(事实上session的获取于释放是一个令人头疼的问题)等等,我们通常会使用HibernateTemplate的excute方法来进行数据库操作(即使我们调用的也许是别的类似于find、get之类的方法,但是实质上最终还是转变为了调用excute方法)。对于第一次使用这个方法一定会存在困扰。因为excute方法所需要的参数一个HibernateCallback类型的参数。而在excute方法体内部回调了HibernateCallback类型的doInHibernate方法。这是一个典型的对象回调。就到目前为止也许一切都很清晰。但是实际上如果阅读了HibernateTemplate的内部代码就会发现,对于像get、find这样的方法最终都回调用excute来完成数据库操作但是调用形式看起来却很奇怪:

public Object get(final Class entityClass, final Serializable id, final LockMode lockMode)

        throws DataAccessException

    {

        return execute(new HibernateCallback() {

            public Object doInHibernate(Session session)

                throws HibernateException

            {

                if(lockMode != null)

                    return session.get(entityClass, id, lockMode);

                else

                    return session.get(entityClass, id);

            }

        }, true);

    }

    Excute方法的参数是一种匿名类的方式。为什么要采用匿名类呢(不管怎么说匿名类看起来总是让人觉得不舒服)?这个地方是否必须采用匿名类呢?

    首先我们来想一想这段代码涉及到几个关键点:1、回调:excute方法会回调HibernateCallback类型的doInHibernate方法;2、匿名类参数:我们为excute方法提供的参数并不是一个真正生命出来的HibernateCallback实例。3、动态创建回调方法:如果我们打开HibernateCallback类就会发现,其实这是一个abstract类型的类,而他声明了唯一的一个ie抽象方法就是doInHibernate。问题似乎已经明朗了,如果不采用匿名类,我们需要做的是为HibernateCallback创建一个实现类,并且实现doInHibernate方法。但是最要命的问题是doInHibernate方法的实现对于我们的实际需求来说每一次调用可能都是不一样的(在doInHibernate方法中我们使用session进行数据库操作,对于不同的业务逻辑,方法实现必定是不一样的),采用了匿名类我们不用在代码重创建新的类型,而且可以动态的创建我们所需要的回调函数。

    总结一下,我们上面所讲的并非是如何使用HibernateTemplate这个类。我们得到的结论是:当我们需要动态的创建回调函数的时候,匿名内部类是一个好的方式。注:这种需要动态创建的回调方法通常是一个interface中的接口或者abstract class中的抽象方法。



抱歉!评论已关闭.