学习了spring的HibernateTemplate类部分源码,总结一下自己对回调模式的理解。
在dao里经常有这样的语句
代码
public E findById(Serializable id)
{
return (E) getHibernateTemplate().get(clazz, id);
}
HibernateTemplate类源码
代码
public Object get(Class entityClass, Serializable id) throws DataAccessException {
return get(entityClass, id, null);
}
代码
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);
}
代码
public Object execute(HibernateCallback action) throws DataAccessException {
return execute(action, isExposeNativeSession());
}
代码
public Object execute(HibernateCallback action, boolean exposeNativeSession) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
Session session = getSession();
boolean existingTransaction = 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 = (exposeNativeSession ? 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());
}
}
}
}
HibernateTemplate类是对hibernate操作的封装。如果要自己写hibernate的操作,最麻烦的是那些要检查的错误,而且每一个地方都一样。不一样的地方只是真正对数据库操作的语句。spring的想法是一样的代码抽取出来写成一个HibernateTemplate中的execute方法。execute的方法参数是HibernateCallback接口类。HibernateCallback里面定义了一个doInHibernate的方法。因为这个方法是变的。比如你是查找数据方法应该就是:session.load()。删除数据就是session.delete().这样的话查询数据库的方法用execute方法。
HibernateCallback 接口类
(* 关键在于 为什么要实施这个接口 !!)
代码
public interface HibernateCallback {
Object doInHibernate(Session session) throws HibernateException, SQLException;
}
然后使用内部类的形式把HibernateCallback中的方法doInHibernate实例化。
代码
new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
if (lockMode != null) {
return session.get(entityClass, id, lockMode);
}
else {
return session.get(entityClass, id);
}
}
总的想法就是不变的东西可以抽象出一个方法。比如对异常的检查。变的东西,比如对数据库的操作,抽象出一个接口的方法。
总结
JAVA的CALLBACK通过接口来实现。
例:
1.HibernateTemplate,内联类
2.内联类实现接口HibernateCallback的doInHibernate 方法
3.HibernateTemplate拥有一个参数为HibernateCallback接口类型的函数execute(HibernateCallback action)方法.
4.调用HibernateTemplate的get方法时,将内联类传给了excute方法
5.执行excute方法时,(你调用它)
已取得内联类,就可以随时回调它所实现的HibernateCallback接口中的方法了,
这时它反过来调用你的方法(它调用你),这就是回调了.
就是调用系统的一个方法,传进去一个接口的实现类 or 匿名类。
然后系统的方法调用接口申明的方法,并且注入相应的参数
Buaawhl:
IoC, Functor, Visitor 都是 callback。
就是一个 Template Methond 里面的flow不变,某一个步骤的具体操作变化,这个变化部需要 从外部(参数,或者属性,或者 override parent method)注入。
类似于从前的 C 回调函数指针。
MainFlow ( callback ){
step1;
....
callback( someThing );
....
stepN;
}
注意配置文件里applictionContext.xml
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="baseTransactionProxy" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
分享到:
相关推荐
**HibernateTemplate** 是 Spring 框架中用于简化 Hibernate 使用的一个工具类。它通过 AOP(面向切面编程)的思想,封装了大量的 CRUD(创建、读取、更新、删除)操作,使得开发者能够更加专注于业务逻辑的实现,而...
HibernateTemplate提供了许多实用的方法来操作数据库,包括批量更新、删除、检查写操作、清除Session缓存、关闭迭代器、检查对象是否在缓存中、创建代理Session对象、删除持久化实例、启用Hibernate过滤器、从缓存...
`HibernateTemplate`提供了一种统一的异常处理机制,可以将Hibernate抛出的各种异常转换为Spring的`DataAccessException`异常层次结构中的异常。这有助于应用程序以一致的方式处理所有数据访问异常。 ```java ...
在Java持久化框架Hibernate中,HibernateTemplate是一个便捷的工具类,它封装了常见的数据库操作,使得开发者能够更方便地与数据库交互。以下是对标题和描述中提到的HibernateTemplate方法的详细总结: A. `get` 和...
4. **内部类回调函数**:在Action类中,我们可以创建一个内部类来实现分页逻辑。这个内部类通常继承自Struts2的ResultSupport类,覆盖execute方法,这样我们可以在回调函数中处理分页的相关逻辑,例如计算总页数、...
使用`TransactionTemplate`,你可以确保所有操作都在同一个事务内,即使在回调方法中包含了多个数据访问操作,事务也会在回调方法完成后统一提交或回滚,根据事务的隔离级别和传播行为。 以下是一个使用`...
它通过回调机制(HibernateCallback)对Hibernate的操作进行封装,使开发者能够以一种更面向对象的方式处理数据库交互。例如,你可以通过实现HibernateCallback接口的doInHibernate方法,传入一个回调函数,执行特定...
// 回调 callback.doInHibernate(s); s.getTransaction().commit(); } catch (Exception e) { s.getTransaction().rollback(); } finally { s.close(); s = null; } } private Session getSession() { ...
通过`HibernateTemplate`的`execute`方法传入一个实现了`HibernateCallback`接口的对象,可以在回调方法中执行任意的Hibernate操作。 ```java public class PersonDaoImpl extends HibernateDaoSupport implements ...
1. 支持JPA 2.1规范:提供了新的查询元素,如TemporalType,以及更丰富的实体生命周期回调。 2. 强化了第二级缓存:引入了对查询结果的缓存支持,提高了系统响应速度。 3. 优化了HQL和JPQL查询:增强了类型安全性和...
通过实现这个接口,可以在执行特定数据库操作前后的回调函数中进行额外的工作,如事务控制、日志记录等。 6.5.6 使用IoC容器组装各种组件 Spring的IoC容器是其核心特性之一,它负责管理应用中的对象及其依赖关系。...
Spring还支持使用回调机制(如HibernateCallback)处理特殊查询和分页。 Hibernate的核心在于对象关系映射,它允许我们将Java对象直接映射到数据库表。开发者需要正确配置实体类(Entity)和数据访问对象(DAO),...
在这个例子中,如果在事务回调方法中抛出未检查异常(继承自RuntimeException的异常)或者受检异常(需要在方法签名中声明的异常),那么事务将会自动回滚。否则,当事务回调方法正常结束时,事务会自动提交。 然而...
`queryForPage`利用`HibernateTemplate`的`executeFind`方法,通过回调接口`HibernateCallback`在Hibernate Session中执行查询并设置分页参数。`getAllRowCount`则直接通过`getHibernateTemplate().find(hql).size()...
在回调方法`doInHibernate`中,通过`createQuery()`创建Query对象,然后使用`setFirstResult()`设置起始位置(即偏移量),`setMaxResults()`设置每页条目数量,最后执行`list()`获取结果集。 2. `findByPage...
`getHibernateTemplate().executeFind()`方法允许我们在回调方法中像操作原生Hibernate一样设置分页参数。 接下来,为了更好地管理分页信息,我们可以创建一个名为`PaginationInfo`的类,该类通常包含以下属性: - ...
此外,`HibernateTemplate`还支持`HibernateCallback`接口,允许开发者在回调方法`doInHibernate(Session session)`中使用原生的Hibernate API,以应对更复杂的数据访问需求。这种方法确保了灵活性,即使在Spring的...
在`queryForPage`方法中,通过`HibernateTemplate`的`executeFind`方法,我们可以传递一个`HibernateCallback`实例,该回调内部创建`Query`对象并设置分页参数`setFirstResult`和`setMaxResults`。`getAllRowCount`...
`queryForPage`方法利用了Spring的`HibernateTemplate`,通过回调机制执行`HibernateCallback`,在回调的内部创建`Query`对象,设置分页参数`setFirstResult`和`setMaxResults`,然后执行查询并返回结果。...