Spring中的HibernateTemplate

linweihan1984發表於2007-10-16
就類似JdbcTemplate一樣,HibernateTemplate封裝了Hibernate儲存時的一些細節,例如try...catch的例外處理等等,HibernateTemplate的使用在觀念上與JdbcTemplate是類似的,這邊簡單的介紹一下HibernateTemplate的使用。

  首先我們看一下Bean定義檔,這與前一個主題沒什麼太大的差別:

 程式碼:

xml 程式碼
 
xml 程式碼
  1. <?xml version="1.0" encoding="UTF-8"?>    
  2. <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd">    
  3. <beans>    
  4.     <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">    
  5.         <property name="driverClassName">    
  6.             <value>com.mysql.jdbc.Driver</value>    
  7.         </property>    
  8.         <property name="url">    
  9.             <value>jdbc:mysql://localhost:3306/TestDB</value>    
  10.         </property>    
  11.         <property name="username">    
  12.             <value>caterpillar</value>    
  13.         </property>    
  14.         <property name="password">    
  15.             <value>123456</value>    
  16.         </property>    
  17.     </bean>    
  18.        
  19.     <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean" destroy-method="close">    
  20.         <property name="dataSource">    
  21.             <ref bean="dataSource"/>    
  22.         </property>    
  23.         <property name="mappingResources">    
  24.             <list>    
  25.                 <value>User.hbm.xml</value>    
  26.             </list>    
  27.         </property>    
  28.         <property name="hibernateProperties">    
  29.             <props>    
  30.                 <prop key="hibernate.dialect">    
  31.                     net.sf.hibernate.dialect.MySQLDialect    
  32.                 </prop>    
  33.                 <prop key="hibernate.show_sql">    
  34.                     true    
  35.                 </prop>    
  36.             </props>    
  37.         </property>    
  38.     </bean>    
  39.   
  40.   
  41.     <bean id="userDAO" class="onlyfun.caterpillar.UserDAO">    
  42.         <property name="sessionFactory">    
  43.             <ref bean="sessionFactory"/>    
  44.         </property>    
  45.     </bean>    
  46. </beans>  

  在這邊UserDAO將繼承自HibernateDaoSupport類別,這可以幫我們省去一些管理sessionFactory、hibernateTemplate資源的工作,我們只要注入sessionFactory就好了,我們的DAO設計如下:

 程式碼:

UserDAO.java
package onlyfun.caterpillar; 

import net.sf.hibernate.*; 
import org.springframework.orm.hibernate.*; 
import org.springframework.orm.hibernate.support.*; 


public class UserDAO extends HibernateDaoSupport { 
    public void insertUser(final User user) { 
        getHibernateTemplate().execute(new HibernateCallback() { 
                public Object doInHibernate(Session session) throws HibernateException { 
                    session.saveOrUpdate(user); 
                    return null; 
                } 
            }); 
    } 
}

  只要注入sessionFactory,之後呼叫getHibernateTemplate()就可以取得HibernateTemplate的例項,我們利用callback方法,實作HibernateCallback介面,在doInHibernate()中進行儲存操作。

  對於簡單的儲存操作,我們甚至可以直接使用HibernateTemplate所提供的find()、load()、saveOrUpdate()、delete()等方法,而不用使用callback,例如:

 程式碼:

UserDAO.java
package onlyfun.caterpillar; 

import org.springframework.orm.hibernate.support.*; 

public class UserDAO extends HibernateDaoSupport { 
    public void insertUser(User user) { 
        getHibernateTemplate().saveOrUpdate(user); 
    } 
}

  不用懷疑,程式就是如此簡單,所有的細節都被封裝起來了。

  HibernateTemplate中只能丟出unckecked例外,如果需要處理checked例外,則您可以使用AOP Interceptor來取代HibernateTemplate,從而取代callback方法,在參考手冊中有介紹如何配置,這邊複製過來以便參考:

 程式碼:

xml 程式碼
  1. ....    
  2.     <bean id="myHibernateInterceptor"    
  3.         class="org.springframework.orm.hibernate.HibernateInterceptor">    
  4.         <property name="sessionFactory">    
  5.             <ref bean="mySessionFactory"/>    
  6.         </property>    
  7.     </bean>    
  8.   
  9.     <bean id="myProductDaoTarget" class="product.ProductDaoImpl">    
  10.         <property name="sessionFactory">    
  11.             <ref bean="mySessionFactory"/>    
  12.         </property>    
  13.     </bean>    
  14.   
  15.     <bean id="myProductDao" class="org.springframework.aop.framework.ProxyFactoryBean">    
  16.         <property name="proxyInterfaces">    
  17.             <value>product.ProductDao</value>    
  18.         </property>    
  19.         <property name="interceptorNames">    
  20.             <list>    
  21.                 <value>myHibernateInterceptor</value>    
  22.                 <value>myProductDaoTarget</value>    
  23.             </list>    
  24.         </property>    
  25.     </bean>    
  26. ....   

 程式碼:

ProductDaoImpl.java
public class ProductDaoImpl extends HibernateDaoSupport implements ProductDao { 

    public List loadProductsByCategory(final String category) throws MyException { 
        Session session = SessionFactoryUtils.getSession(getSessionFactory(), false); 
        try { 
            List result = session.find( 
                "from test.Product product where product.category=?", 
                category, Hibernate.STRING); 
            if (result == null) { 
                throw new MyException("invalid search result"); 
            } 
            return result; 
        } 
        catch (HibernateException ex) { 
            throw SessionFactoryUtils.convertHibernateAccessException(ex); 
        } 
    } 
}

相關文章