擴(kuò)展Spring(2) ---Spring對各種數(shù)據(jù)訪問框架的集成機(jī)制

     何為數(shù)據(jù)框架集成。
   數(shù)據(jù)訪問框架原本好好的,Spring都干了什么呢?
   一是用template類封裝了數(shù)據(jù)框架那些資源獲取和異常事務(wù)處理的廢話代碼,而且按照自己的意見給出一些增強(qiáng)函數(shù)。
   二是將其納入了Spring的聲明式事務(wù)管理中。

    對比Spring對Hibernate、JDBC的集成,還有Spring ModulesO/R Broker的集成,發(fā)現(xiàn)Spring的DAO框架主要有六個(gè)類:
    1.Template
      著名的Template類,用callback機(jī)制封裝了除業(yè)務(wù)代碼外的所有必要但廢話的代碼,重新封裝了數(shù)據(jù)框架的API,并再附送一些增強(qiáng)版。

    2.TransactionManager 
      實(shí)現(xiàn)PlatformTransactionManager接口,數(shù)據(jù)訪問框架就能與Spring的事務(wù)機(jī)制(TransactionTemplate或AOP聲明式事務(wù))結(jié)合。

    重要的類僅以上兩個(gè),以下的類都只有少量標(biāo)準(zhǔn)代碼,完全可以忽略。
    
3.DAOSupport
       實(shí)際DAO類的基類,負(fù)責(zé)保持template變量。如果你覺得它破壞了你的類層次結(jié)構(gòu),完全可以不用。
    4.Accessor
     template類的基類,defining common properties like DataSource and exception translator,也沒大用。
    5.Operations
     template所實(shí)現(xiàn)的接口,定義template支持的數(shù)據(jù)訪問函數(shù)和增強(qiáng)函數(shù),template有多個(gè)實(shí)現(xiàn)時(shí)才有用。
    6.Exception Translate的相關(guān)類和函數(shù)
     異常翻譯,Spring DAO很重視的一個(gè)功能。

Template類的代碼
   因?yàn)镠ibernate本身很復(fù)雜,所以HibernateTemplate也不適合畏高暈車的人士如我觀看。JDBC簡單很多,但JDBCTemplate又忙著增強(qiáng)JDBC的功能,多出好多代碼。所以我選O/R broker的集成代碼來看,代碼一共才280行。
注:如果不熟O/R broker,可以簡單的認(rèn)為broker=connection, executable = statement ,其余一切同Jdbc。

1.1主干函數(shù) Execute(BrokerCallback action)
      step1. 獲得Connection-- connecton = datasource.getConn();
      step2. 準(zhǔn)備Statement -- statement = new Statement(connection);
      step3. 執(zhí)行Action的回調(diào)函數(shù)doInBroker(Statement)。這個(gè)doInBroker()方法由客戶定義,會拿著傳入的statement,執(zhí)行種種操作。
              
 try
{
  action.doInBroker(statement );
}
catch()
{
   
//翻譯異常
}

   1.2 template的API函數(shù)
         雖然理論上大家可以直接使用execute(),在匿名內(nèi)部類里調(diào)用數(shù)據(jù)訪問框架的任何API。但java的匿名內(nèi)部類不比閉包,代碼難看無比,所以除了Robbin還沒見到其他兄弟提倡直接用execute方法的。
        因此,template也對數(shù)據(jù)框架的API進(jìn)行了wrap,封裝了用execute(StatementCallback action)來執(zhí)行這些API的函數(shù),如下段就是wrap 了O/R Broker的execute(String statementID.....)方法:
public int execute(final String statementID, final String[] paramNames, final Object[] values) throws DataAccessException {
    
return executeWithIntResult(new BrokerCallback() {
      
public Object doInBroker(Executable executable) throws BrokerException {
        applyNamedParamsToExecutable(executable, paramNames, values);
        
return new Integer(executable.execute(statementID));
      }
    });
  }


    另外還提供一些增強(qiáng)型、便利型的API(如selectOne() ,selectMany()),在參數(shù)、返回值上極盡變化。

TransactionManager的代碼
   比較復(fù)雜,一下說不清。但JDBC的DatasourceTransactionManager和Hibernate的HibernateTransactionManager的代碼都很相近,說明這個(gè)TransactionManager其實(shí)也比較固定埋頭狂抄就是了。

    有興趣的同學(xué),可以響應(yīng)某大老號召,實(shí)現(xiàn)ofbiz與spring的集成:)

系列文章:
Spring 的微內(nèi)核與FactoryBean擴(kuò)展機(jī)制
擴(kuò)展Spring(2)--Spring對各種數(shù)據(jù)訪問框架的集成機(jī)制