关键字: HibernateCallback 接口
对于特定的数据访问对象或业务对象的方法来说,基本的模板编程模型看起来象下面所示的代码那样。对于这些外部对象来说,没有任何实现特定接口的要求,仅仅要求提供以个Hibernate SessionFactory. 它可以从任何地方得到,不过比较适宜的方法是从Spring的applicationcontext中得到的bean引用:通过简单的setSessionFactory(..)这个bean的setter方法。
[beans]
...
[bean id="myProductDao" class="product.ProductDaoImpl"]
[property name="sessionFactory" ref="mySessionFactory"/]
[/bean]
[/beans]
public class ProductDaoImpl implements ProductDao{
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}
public Collection loadProductsByCategory(final String category) throws DataAccessException {
HibernateTemplate ht = new HibernateTemplate(this.sessionFactory);
return (Collection) ht.execute(
new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
Query query = session.createQuery("from test.Product product where product.category=?");
query.setString(0, category);
return query.list();
}
}
);
}
}
一个回调实现能够有效地在任何Hibernate数据访问中使用。HibernateTemplate 会确保当前Hibernate的 Session 对象的正确打开和关闭,并直接参与到事务管理中去。 Template实例不仅是线程安全的,同时它也是可重用的。因而他们可以作为外部对象的实例变量而被持有。对于那些简单的诸如find、load、saveOrUpdate或者delete操作的调用,HibernateTemplate 提供可选择的快捷函数来替换这种回调的实现。 不仅如此,Spring还提供了一个简便的 HibernateDaoSupport 基类,这个类提供了 setSessionFactory(..) 方法来接受一个 SessionFactory 对象,同时提供了 getSessionFactory() 和 getHibernateTemplate() 方法给子类使用。 综合了这些,对于那些典型的业务需求,就有了一个非常简单的DAO实现:
public class ProductDaoImpl extends HibernateDaoSupport implements ProductDao {
public Collection loadProductsByCategory(String category) throws DataAccessException {
return getHibernateTemplate().find(
"from test.Product product where product.category=?", category);
}
}