Spring Template(3) ——ORM 設計與實現,templateorm
通常情況下,ORM用的最多的是Hibernate。使用它,除了需要處理像Session、SessionFactory這些Hibernate類之外,還需要處理諸如交易處理、開啟Session和關閉Session這樣的問題,在某種程度上增加了使用Hibernate的難度。而Spring提供的Hibernate封裝,如HibernateDaoSupport、HIbernateTemplate等,簡化了這些通用過程。
Spring的ORM包提供了對許多ORM產品的支援。通常使用Spring提供的Template類。在這些模板類裡,封裝了主要的資料操作方法,比如query、update等,並且在Templdate封裝中,已經包含了Hibernate中Session的處理,Connection的處理、事務的處理等。通過封裝將Hibernate的持久化資料操作納入到Spring統一的交易處理架構中,這部分是通過Spring的AOP來實現的。
類圖:
DaoSupport是一個核心類,通過HIbernateTemplate支援對HIbernate的操作。
Spring的ORM模組並不是重新開發的,通過IOC容器和AOP模組對Hibernate的使用進行封裝。使用HIbernate,需要對HIbernate進行配置,這些配置通過SessionFactory來完成,在Spring的HIbernate模組中,提供了LocalSessionFactoryBean來封裝SessionFactory的配置,通過這個LocalSessionFactory封裝,可以將SessionFactory的配置資訊通過Bean定義,注入到IOC容器中執行個體化好的SessionFactory單例對象中。這個LocalSessionFactoryBean設計為HIbernate的使用奠定了基礎。
以hibernateTemplate為例
與JdbcTemplate的使用類似,Spring使用相同的模式,通過execute回調來完成。如下:
代碼
public <T> T execute(HibernateCallback<T> action) throws DataAccessException{return doExecute(action,false,false);}protected <T> T doExecute(HIbernateCallback<T> action,boolean enforceNewSession,boolean enforceNativeSession) throws DataAccessException{Assert.notNull(action,"Callback object must not be null");//這裡是取得HIbernate的Session,判斷是否強制需要新的Session,//如果需要,則直接通過SessionFactory開啟一個新的session,否則需要結合配置和當前的Transaction的情況來使用SessionSession session = (enforceNewSession ? SessionFactoryUtils.getNewSession(getSessionFactory(),getEntityInterceptor()):getSession());//判斷Transaction是否已經存在,如果是,則使用的就是當前的Transaction的sessionboolean 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));//這裡是對HIbernateCallback中回呼函數的調用,Session作為參數可以由回呼函數使用T result = action.doInHibernate(sessionToExpose);flushIfNecessary(session,existingTransaction);return result;} catch (HibernateException ex) {throw convertHibernateAccessException(ex);}catch(SQLException ex){throw convertJdbcAccessException(ex);}catch(RuntimeException ex){throw ex;//如果存在Transaction,當前回調完成使用完session後,不關閉這個session}finally{if(existingTransaction){logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");disableFilters(session);if(previousFlushMode != null){session.setFlushMode(previousFlushMode);}}//如果不存在Transaction,那麼關閉當前Sessionelse{if(isAlwaysUseNewSession()){SessionFactoryUtils.closeSession(session);}else{SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session,getSessionFactory());}}}}
總結
Spring封裝了交易處理,以及通過HIbernateTemplate封裝了Session,不直接對Session進行操作。
Spring不提供具體的ORM實現,只為應用提供對ORM產品的Integration Environment和使用平台。並且Spring封裝的Hibernate的API,方便了使用者。