spring之orm组件

开发中最常用的orm框架以hinernate和ibatis居多,就拿hibernater介绍

 

先看类图:

 

这个类图结构是spring对持久层的一个通用架构。比如对JDBC的支持,Jpa的支持

你可以在程序中直接使用HibernateTemplate也可以通过继承HibernateDaoSupport来实现对持久层的操作。

 

然后看一下LocalSessionFactoryBean的结构图

从上图中可以看到LocalSessionFactoryBean 实现了spring的生命周期接口,并且实现了factoryBean,这就意味这可以通过getObject方法对bean在做一次包装。但是比较失望的是LocalSessionFactoryBean的getObject只是单纯的返回了sessionFactory


 /**
  * Return the singleton SessionFactory.
  */
 public Object getObject() {
  return this.sessionFactory;
 }

 

继续参看SessionFactory

那么SessionFactory是什么时候加载的呢

可以看到是AbstractSessionFactoryBean持有,而AbstractSessionFactoryBean实现了InitializingBean这个接口,意味当bean实例化结束后会执行afterPropertiesSet这个方法

继续看afterPropertiesSet这个方法。

public void afterPropertiesSet() throws Exception {
  SessionFactory rawSf = buildSessionFactory();
  this.sessionFactory = wrapSessionFactoryIfNecessary(rawSf);
  afterSessionFactoryCreation();
 }

一切都明白了,当bean被实例化后会调用afterPropertiesSet去加载SessionFactory

AbstractSessionFactoryBeans 抽象了创建SessionFactory的方法protected abstract SessionFactory buildSessionFactory() throws Exception;

子类 LocalSessionFactoryBean 实现了这个方法。具体代码不粘贴了,代码主要是对config的过程。之后调用

protected SessionFactory newSessionFactory(Configuration config) throws HibernateException {
  return config.buildSessionFactory();
 }

生成了我们要的SessionFactory。

那么我们如何通过spring来操作hibernate呢?

和对jdbc的支持一样,spring提供了hibernateTemplate模版方代码法。研究之前,简要的回顾下gof的模版模式。

 
将公用的方法抽出来放到抽象的父类里,子类只需要实现自己的行为。 spring对orm的支持到处都是使用了这样一种(模版+回调)的模式。
 
通过上图可以看出spring如何通过hibernateTemplate操作hibernate的。其中HibernateCallback提供回调接口方法doInHibernate。参考下面代码
 
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的回调后再调用session的flush方法实现对数据库和一级缓存的同步。

这样我们开发的时候只需要了解HibernateTemplate提供的save/update等方法就好,其他的细节都由spring封装好了。

通过下面的代码了解具体的细节:

 protected Object doExecute(HibernateCallback action, boolean enforceNewSession, boolean enforceNativeSession)
   throws DataAccessException {

  Assert.notNull(action, "Callback object must not be null");  //回调方法不能为空
        //enforceNewSession 是否创建一个新的session  如果是则SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor())
  Session session = (enforceNewSession ?
    SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor()) : getSession());
  //是不是存在事务   isAllowCreate 在所有线程上都找不到绑定的session后,是否允许创建新的session
  //SessionFactoryUtils.isSessionTransactional(session, getSessionFactory())) 
  //判断session是否被spring事务管理器绑定到当前线程上,也就是说这个session是否具备
  //是判断逻辑为TransactionSynchronizationManager持有的sessionHolder里是否包含当前的session
  boolean existingTransaction = (!enforceNewSession &&
    (!isAllowCreate() || SessionFactoryUtils.isSessionTransactional(session, getSessionFactory())));
  if (existingTransaction) {
   logger.debug("Found thread-bound Session for HibernateTemplate");
  }

  FlushMode previousFlushMode = null;
  try {
   //将flushModel设置到session中
   previousFlushMode = applyFlushMode(session, existingTransaction);
   enableFilters(session);
   //使用原生session还是使用代理proxy
   Session sessionToExpose =
     (enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session));
   //执行HibernateCallback回调方法
   Object result = action.doInHibernate(sessionToExpose);
   //调用session的flush
   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) {
     //存在事务,不关闭session
    logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");
    disableFilters(session);
    if (previousFlushMode != null) {
     session.setFlushMode(previousFlushMode);
    }
   }
   else {
    //不存在事务,关闭session
    // Never use deferred close for an explicitly new Session.
    if (isAlwaysUseNewSession()) {
     SessionFactoryUtils.closeSession(session);
    }
    else {
     SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory());
    }
   }

  }
 }

从上面这段代码可以看出其实spring使用的就是hibernate的原生API。

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值