- 浏览: 780276 次
- 性别:
- 来自: 西安
文章分类
最新评论
-
wangyudong:
新版本 Wisdom RESTClienthttps://gi ...
jersery client调用REST框架web services服务的一个示例 -
wangyudong:
很多REST Client是不支持自动化测试RESTful A ...
jersery client调用REST框架web services服务的一个示例 -
doubledumbao:
感谢你的代码,在使用中发现两处小问题,已经做了修改,再次感谢。 ...
Java Zip Utils 压缩/解压缩工具包 -
doubledumbao:
package com.ry.messagedigest;
...
Java Zip Utils 压缩/解压缩工具包 -
phrmgb:
对wsdl讲解的很细致,收藏
Web Service (二) WSDL详解
Spring中 Callback模式和Template模式合用 随处可见。下面以常用的HibernateTemplate为例进行简要简述。
在HibernateTemplate模板类中有一个核心的方法:doExecute,这个核心的方法采用模板方法 完成相关的固定 操作(建立连接,执行操作,释放连接) ,其中的具体步骤通过回调传入的对象(这个对象就是实现了Callback接口的类)来完成。
一。HibernateTemplate类的使用:
1。HibernateTemplate 类提供了大量方法对应Hibernate Session 接口中暴露的方法。使用这些方法时可以直接调用。save()方法使用例子:
import org.springframework.orm.hibernate3.HibernateTemplate; @Component("userDaoImpl") public class UserDaoImpl implements UserDao { private HibernateTemplate hibernateTemplate; public HibernateTemplate getHibernateTemplate() { return hibernateTemplate; } @Resource(name="hibernatTemplate") public void setHibernateTemplate(HibernateTemplate hibernateTemplate) { this.hibernateTemplate = hibernateTemplate; } @Override public void save(User u) { hibernateTemplate.save(u); //这里可以直接save了,session已经被hibernateTemplate处理了。我们不需要关心它了。 //因为HibernateTemplate中已经注入了SessionFactory了,因为它自己会处理好session及其事务的。 System.out.println("user save..."); }}
因为HibernateTemplate需要交给Spring来管理,因为也需要配置bean,及注入sessionFactory:
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory"/> </bean>
2。当你需要使用的Session
方法没有在HibernateTemplate
中提供时,可以通过下面提供的基于回调的方案来实现,如下实例所示:
public class ProductDaoImpl implements ProductDao { private HibernateTemplate hibernateTemplate; public void setSessionFactory(SessionFactory sessionFactory) { this.hibernateTemplate = new HibernateTemplate(sessionFactory); } public Collection loadProductsByCategory(final String category) throws DataAccessException { return this.hibernateTemplate.execute(new HibernateCallback() { public Object doInHibernate(Session session) { Criteria criteria = session.createCriteria(Product.class); criteria.add(Expression.eq("category", category)); criteria.setMaxResults(6); return criteria.list(); } }; } }
3。HibernateDaoSupport 基类:
一个回调实现能够有效地在任何Hibernate数据访问中使用。HibernateTemplate 会确保当前Hibernate的 Session 实例的正确打开和关闭,并直接参与到事务管理中去。 Template实例不仅是线程安全的,同时它也是可重用的。因而他们可以作为外部对象的实例变量而被持有。对于那些简单的诸如find、load、saveOrUpdate或者delete操作的调用,HibernateTemplate 提供可选择的快捷函数来替换这种回调的实现。 不仅如此,Spring还提供了一个简便的 HibernateDaoSupport 基类,这个类提供了 setSessionFactory(..) 方法来接受一个 SessionFactory 对象,同时提供了 getSessionFactory() 和 getHibernateTemplate() 方法给子类使用。实例如下:
public class ProductDaoImpl extends HibernateDaoSupport implements ProductDao { public Collection loadProductsByCategory(String category) throws DataAccessException { return this.getHibernateTemplate().find( "from test.Product product where product.category=?", category); } }
4。HibernateDaoSupport 基类使用技巧:
HibernateDaoSupport这也是使用HibernateTemplate的方法之一,只是需要dao继承这个类:
public class LogDaoImpl extends HibernateDaoSupport implements LogDao { @Override public void save(Log log) { this.getHibernateTemplate().save(log); //this.save(log); System.out.println("log save..."); } }
dao继承了HibernateDaoSupport类,而这个又拥有sessionFactory和hibernateTemplate的setXXX方法,只要我在初始化这个dao时,注入两个其中一个就可以了。但是这两个setXX方法都为final的,因为不可以重写,这样就不能使用annotation的方式了,只能使用xml的方法了。HibernateDaoSupport部分源代码如下:
public abstract class HibernateDaoSupport extends DaoSupport{ private HibernateTemplate hibernateTemplate; public final void setSessionFactory(SessionFactory sessionFactory) { //...... } } public final void setHibernateTemplate(HibernateTemplate hibernateTemplate) { this.hibernateTemplate = hibernateTemplate; } public final HibernateTemplate getHibernateTemplate() { return this.hibernateTemplate; } //.......其他方法 }
xml注入方法如下:
<bean id="logDaoImpl" class="example.dao.impl.LogDaoImpl"> <property name="hibernateTemplate" ref="hibernateTemplate"></property> </bean>
但是问题又来了,如果dao有多个(甚至几个以上),这样就会有大量的xml配置文件,每个dao需要一个配置一个bean,并且在这个bean中需要注入一个sessionFactory或是hibernateTemplate,这样的工作量是非常的大,并且容易出错。
针对有大量的dao我们提供一个解决方案:
我们可以创建一个类,并且这个类来继承hibernateDaoSupport这个类,由于hibernateDaoSupport类的sessionFactory和hibernateTemplate的setXXX方法是final的,因此不能重写,但我们可以在这个类中注入一个sessionFactory或hibernateTemplate但是setXXX方法名,用其它的。然后让dao来继承这个类,这就dao就可以使用annotation方式注解了。代码如下:
@Component public class SuperDao extends HibernateDaoSupport { @Resource(name="hibernateTemplate") public void setSuperHibernateTemplate(HibernateTemplate hibernateTemplate ){ //在这里为父类HibernateDaoSuppport注入hibernateTemplate或是sessionFactory super.setHibernateTemplate(hibernateTemplate); } }
其它的dao继承这个就可以了,如下所示:
@Component public class LogDaoImpl extends SuperDao implements LogDao { @Override public void save(Log log) { this.getHibernateTemplate().save(log); //this.save(log); System.out.println("log save..."); } }
其他的用法不在这里累述,请参看Spring的参考文档.下面重点说说Spring HibernateTemplate模板方法与Callback机制.
二。HibernateTemplate源码分析
下面以save()方法为例进行说明,先看源代码:
HibernateCallback接口的代码如下, 它只有一个方法doInHibernate方法:
public interface HibernateCallback { Object doInHibernate(Session session) throws HibernateException, SQLException; }
HibernateTemplate中的具体操作的方法,如save(),update()的具体实现都采用匿名类的方式实现了该接口,在doInHibernate中完成具体的操作。以save()方法为例:
public Serializable save(final Object entity) throws DataAccessException { return (Serializable) executeWithNativeSession(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { checkWriteOperationAllowed(session); return session.save(entity); } }); }
这段代码重点注意以匿名类的方式实现了 HibernateCallback接口.
然后是executeWithNativeSession()方法如下,在此方法中调用核心方法doExecute,如下所示:
public Object executeWithNativeSession(HibernateCallback action) { return doExecute(action, false, true); }
在这个方法中使用本地已存在的Session去执行此次save操作,doExecute代码如下所示:
/** * Execute the action specified by the given action object within a Session. * @param action callback object that specifies the Hibernate action * @param enforceNewSession whether to enforce a new Session for this template * even if there is a pre-bound transactional Session * @param enforceNativeSession whether to enforce exposure of the native * Hibernate Session to callback code * @return a result object returned by the action, or <code>null</code> * @throws org.springframework.dao.DataAccessException in case of Hibernate errors */ protected Object doExecute(HibernateCallback action, boolean enforceNewSession, boolean enforceNativeSession) throws DataAccessException { Assert.notNull(action, "Callback object must not be null"); Session session = (enforceNewSession ? SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor()) : getSession()); boolean existingTransaction = (!enforceNewSession && (!isAllowCreate() || SessionFactoryUtils.isSessionTransactional(session, getSessionFactory()))); if (existingTransaction) { logger.debug("Found thread-bound Session for HibernateTemplate"); } FlushMode previousFlushMode = null; try { previousFlushMode = applyFlushMode(session, existingTransaction); enableFilters(session); Session sessionToExpose = (enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session)); Object result = action.doInHibernate(sessionToExpose); flushIfNecessary(session, existingTransaction); return result; } catch (HibernateException ex) { throw convertHibernateAccessException(ex); } catch (SQLException ex) { throw convertJdbcAccessException(ex); } catch (RuntimeException ex) { // Callback code threw application exception... throw ex; } finally { if (existingTransaction) { logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate"); disableFilters(session); if (previousFlushMode != null) { session.setFlushMode(previousFlushMode); } } else { // Never use deferred close for an explicitly new Session. if (isAlwaysUseNewSession()) { SessionFactoryUtils.closeSession(session); } else { SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory()); } } } }
doExecute这个方法有点过于复杂,不容易理解,现在我用差不多是伪代码的形式来把doExecute这个方法的大概意思写出为,以便大家理解:
public class MyHibernateTemplate { public Object executeWithNativeSession(HibernateCallback action) { return doExecute(action, false, true); } protected Object doExecute(HibernateCallback action, boolean enforceNewSession, boolean enforceNativeSession){ Session session = null; try { session = getSession(); session.beginTransaction(); action.doInHibernate(session); session.getTransaction().commit(); } catch (Exception e) { session.getTransaction().rollback(); }finally{ //....进行额外处理 } return null; } private Session getSession() { // TODO Auto-generated method stub return new Session(); } }
如果你觉得使用匿名内部类传参的方式不好理解,你可以先写一个特定针对save操作的实现类来帮助理解它,如下所示:
public class HibernateSaveCallbackImpl implements HibernateCallback { private Object object ; public HibernateSaveCallbackImpl(){} public HibernateSaveCallbackImpl(Object object){ this.object = object; } public Object doInHibernate(Session session) throws HibernateException, SQLException { session.save(object); return null; } }
然后再实例化一个HibernateSaveCallbackImpl对象传给MyHibernateTemplate进行使用,如下所示:
public static void main(String[] args) { HibernateCallback callback = new HibernateSaveCallbackImpl(); HibernateCallback callback2 = new HibernateSaveCallbackImpl("save this object"); new MyHibernateTemplate().executeWithNativeSession(callback); }
当MyHibernateTemplate中的doExecute方法执行时,执行到
action.doInHibernate(session);
时,它会先去执行你传入的引用(也就是你自己)的方法。所以称为回调,这与模板模式中的钩子函数基本是一样的。其实回调,简单的可以说是:将自己的引用传给别的方法,在别的方法里面,通过自己的引用调用自己的方法。
发表评论
-
使用Spring进行面向切面(AOP)编程
2010-07-22 23:54 84701.aop理论知识 横切性关注点:对哪些方法拦截,拦截后怎么 ... -
Spring MVC入门
2010-07-19 13:54 2433在Web MVC架构中,用户并不直接连接至所需的资源,而 ... -
使用JDK中的Proxy技术、CGLIB实现AOP功能
2010-07-12 22:44 2053应用——>代理对象——>目标对象 使用Proxy ... -
Spring自动扫描和管理Bean
2010-07-11 18:18 5577在前面使用注解的时候,除了<beans ... -
依赖注入实现方式
2010-07-11 14:25 2404注入依赖对象可以采用 手工装配或自动装配,在实际应用中 ... -
Spring依赖注入配置详解
2010-06-14 15:42 2992bean的属性及构造器 ... -
Spring 依赖注入
2010-06-14 15:22 2003本文内容主要来自于Spring Reference. ... -
Bean的作用域及生命周期
2010-04-30 23:24 4651一、Spring Framework支持五种作用域(其中有三种 ... -
三种实例化Bean的方式
2010-04-28 22:45 2035从本质上来说,bean定义描述了如何创建一个或多个对象实例 ... -
编码剖析Spring管理Bean的原理
2010-04-28 21:54 1251以下内容来自于传智播客Spring视频,如有雷同,并非巧合。 ... -
了解Spring
2010-04-27 23:04 868下面的一系列的文章的所有内容主要来源于Spring2.5 Re ...
相关推荐
在Spring框架中,`HibernateTemplate`是一个非常重要的组件,它为开发者提供了与Hibernate持久化库交互的便捷方式。然而,正如描述中所指出的,直接使用`HibernateTemplate`进行事务管理并不总是最佳实践,尤其是在...
《Spring与Hibernate整合:深入理解HibernateTemplate》 在Java企业级开发中,Spring框架和Hibernate持久层框架的结合使用是常见的技术选型。本篇将深入探讨Spring与Hibernate的集成,特别是Spring提供的...
**Spring与Hibernate的整合** Spring通过HibernateTemplate提供了一种便捷的方式,将Hibernate的数据库操作纳入到Spring的管理之下。通过Spring的事务管理,开发者可以声明式地控制事务边界,使得事务处理更加透明和...
总之,Spring与Hibernate的整合使得数据库操作更加简洁和高效,而依赖注入则进一步增强了代码的可测试性和可维护性。通过理解和实践这个例子,你可以更好地掌握Spring的DI机制以及如何利用HibernateTemplate简化...
将Spring与Hibernate集成,可以充分利用两者的优点,实现高效且灵活的后端数据处理。 在"spring集成hibernate所需jar包"中,通常包含以下关键的库文件: 1. **Spring Framework**:这是Spring的核心组件,包括`...
一、Spring与Hibernate整合的意义 Spring和Hibernate的整合可以简化Java应用的开发,通过Spring对Hibernate的封装,开发者无需直接操作SessionFactory和Session,而是使用更简洁、易用的API,同时还能享受到Spring的...
**Spring与Hibernate集成详解** 在Java企业级应用开发中,Spring和Hibernate是两个非常重要的框架。Spring是一个全方位的轻量级应用框架,提供了强大的依赖注入、AOP(面向切面编程)以及各种服务管理功能。而...
HibernateTemplate是Spring框架提供的一种操作Hibernate的方式,它简化了Hibernate的使用过程,使开发者无需关注Session的管理与事务控制,极大地提高了开发效率。本文将对HibernateTemplate的主要用法进行详细介绍...
此外,通过与Spring框架的良好集成,`HibernateTemplate`能够更好地管理事务边界,从而保证数据的完整性和一致性。在实际开发过程中,合理利用`HibernateTemplate`能够显著提升开发效率,降低维护成本。
`HibernateTemplate`是Spring框架中用于操作Hibernate的一个便捷工具类,它极大地简化了Hibernate在实际应用中的集成与开发工作。通过`HibernateTemplate`,开发者可以非常方便地进行数据的增删改查等基本操作,而...
### HibernateTemplate概述与核心功能详解 #### 一、引言 在Java开发领域,特别是企业级应用开发中,数据持久层的设计与实现至关重要。Hibernate作为一款优秀的对象关系映射(ORM)框架,极大地简化了Java应用程序...
`HibernateTemplate`是Spring框架中的一个类,位于`org.springframework.orm.hibernate3`包下。它提供了一系列简化Hibernate数据访问操作的方法,并且能够自动将Hibernate异常转换为Spring的数据访问异常体系中的...
HibernateTemplate 是 Spring 框架中的一個关键组件,用于简化 Hibernate 的使用,提供了許多实用的方法来进行数据库操作。在本文中,我们将对 HibernateTemplate 的主要方法进行总结和解释。 ...
《轻量级 J2EE 企业应用实战: Struts+Spring+Hibernate 整合开发》一书中详述了Spring与Hibernate的整合,其中一个重要组件就是HibernateTemplate。它为简化Hibernate在Spring框架中的使用提供了便利,减少了手动...
Spring 可以通过工厂方法或 JdbcTemplate、HibernateTemplate 提供的模板方法来获取 Session。 6. **Service 层设计**:Service 层是业务逻辑的核心,通常会注入 DAO 实例并调用其方法来完成业务处理。Service 层...
而`HibernateTemplate`作为Spring框架对Hibernate的一种封装,更是进一步降低了开发难度,提高了开发效率。 #### 二、核心价值:专注业务逻辑 `HibernateTemplate`的主要价值在于让开发者能够将更多的精力聚焦于...
7. **测试与运行**:编写测试用例,确保Spring和Hibernate的配置正确无误,能够正常执行数据库操作。 总的来说,Spring 4.2 和 Hibernate 4.3 的集成配置是一项关键任务,它能够帮助开发者构建健壮、可扩展的应用...
Spring的JdbcTemplate和HibernateTemplate简化了数据库操作。 6. **Spring Boot**:Spring Boot是Spring的一个子项目,旨在简化Spring应用的初始搭建以及开发过程。它提供了默认配置,使得开发者能快速创建独立的、...
在"25_黑马程序员_黎活明_Spring2.5视频教程_搭建和配置Spring与Hibernate整合的环境.avi"这个文件中,可能详细演示了如何配置这些库到项目的类路径中。 接着,需要配置Spring的IoC容器。这可以通过XML配置文件完成...
4. **Spring与Hibernate集成** - 数据源(DataSource)配置:在Spring上下文中定义数据源,作为连接到数据库的桥梁。 - SessionFactory配置:创建SessionFactory,设置相关参数。 - DAO层:DAO类继承...