就類似JdbcTemplate一樣,HibernateTemplate封裝了Hibernate存儲時的一些細節,例如try...catch的例外處理等等,HibernateTemplate的使用在觀念上與JdbcTemplate是類似的,這邊簡單的介紹一下HibernateTemplate的使用。
首先我們看一下Bean定義檔,這與前一個主題沒什麼太大的差別:
代碼:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql: </property>
<property name="username">
<value>caterpillar</value>
</property>
<property name="password">
<value>123456</value>
</property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean" destroy-method="close">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="mappingResources">
<list>
<value>User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
net.sf.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">
true
</prop>
</props>
</property>
</bean>
<bean id="userDAO" class="onlyfun.caterpillar.UserDAO">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
</beans>
在這邊UserDAO將繼承自HibernateDaoSupport類別,這可以幫我們省去一些管理sessionFactory、hibernateTemplate資源的工作,我們只要注入sessionFactory就好了,我們的DAO設計如下:
代碼:
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() {
publicObject doInHibernate(Session session) throws HibernateException {
session.saveOrUpdate(user);
returnnull;
}
});
}
}
只要注入sessionFactory,之後調用getHibernateTemplate()就可以取得HibernateTemplate的實例,我們利用callback方法,實作HibernateCallback介面,在doInHibernate()中進行存儲操作。
對於簡單的存儲操作,我們甚至可以直接使用HibernateTemplate所提供的find()、load()、saveOrUpdate()、delete()等方法,而不用使用callback,例如:
代碼:
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方法,在參考手冊中有介紹如何配置,這邊複製過來以便參考:
代碼:
....
<bean id="myHibernateInterceptor"
class="org.springframework.orm.hibernate.HibernateInterceptor">
<property name="sessionFactory">
<ref bean="mySessionFactory"/>
</property>
</bean>
<bean id="myProductDaoTarget" class="product.ProductDaoImpl">
<property name="sessionFactory">
<ref bean="mySessionFactory"/>
</property>
</bean>
<bean id="myProductDao" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>product.ProductDao</value>
</property>
<property name="interceptorNames">
<list>
<value>myHibernateInterceptor</value>
<value>myProductDaoTarget</value>
</list>
</property>
</bean>
....
代碼:
public class ProductDaoImpl extends HibernateDaoSupport implements ProductDao {
public List loadProductsByCategory(finalString 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) {
thrownew MyException("invalid search result");
}
return result;
}
catch (HibernateException ex) {
throw SessionFactoryUtils.convertHibernateAccessException(ex);
}
}
}