小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

當 Hibernate 遇上 Spring

 亂⑦⑧糟 2006-07-27
當 Hibernate 遇上 Spring

作者:Naveen Balani    來自:IBM

  在這個系列的 前一期中,我介紹了 Spring 框架的 7 個模塊,包括 Spring AOP 和控制反轉(IOC)容器。然后我用一個簡單的示例演示了 IOC 模式(由 Spring IOC 容器實現)如何用松散耦合的方式集成分散的系統(tǒng)。

  現在,我從我上次結束的地方開始,采用與上次類似的示例,演示 Spring AOP 和 Spring Hibernate 持久性支持的聲明性事務處理,所以我首先從對這兩項技術的深入研究開始。

  Spring AOP

  軟件系統(tǒng)通常由多個組件構成,每個組件負責一個特定的功能領域。但是,這些組件也經常承擔它們的核心功能之外的額外責任。系統(tǒng)服務(例如日志、事務管理和安全性)經常發(fā)現自己跑到了別的組件的領域里,而這些組件的核心職責是其他事情。結果就是所謂的“代碼糾纏”,或者更簡單點兒說“一團糟”。面向方面編程是一種試圖解決這個問題的編程技術,它把關注點的隔離提升為核心的編程概念。

  使用 AOP 時,仍然是在一個地方定義系統(tǒng)的公共功能,但是可以聲明性地定義 如何 和 在哪里 應用這個功能。如果對橫切關注點(例如日志和事務管理)進行了模塊化,那么不用修改每個單獨的類,就可以向代碼中添加新特性。這類模塊化的關注點稱作 方面。
 
  以一個企業(yè)應用程序為例。這類應用程序通常要求類似于安全性和事務支持的服務。顯然,可以把這些服務的支持直接編寫到要求服務的每個類當中,但是更希望能夠不必為大量事務性上下文編寫同樣的事務處理代碼。如果使用 Spring AOP 進行事務處理,那么可以聲明性地安排適當的方法調用,而不必逐個安排。

  Spring AOP 提供了幾個方面,可以為 JavaBean 聲明事務。例如,TransactionProxyFactoryBean 是個方便的代理類,能夠攔截對現有類的方法調用,并把事務上下文應用到事務 bean。在下面的示例中會看到這個類的實際應用。

  Hibernate

  Spring 框架提供了對 Hibernate、JDO 和 iBATIS SQL Maps 的集成支持。Spring 對 Hibernate 的支持是第一級的,整合了許多 IOC 的方便特性,解決了許多典型的 Hibernate 集成問題。框架對 Hibernate 的支持符合 Spring 通用的事務和數據訪問對象(DAO)異常層次結構。

  Spring 為使用選擇的 OR 映射層來創(chuàng)建數據訪問應用程序提供了支持。因為所有東西都設計成一組可重用 JavaBean,所以不管選擇什么技術,都能以庫的格式訪問大多數 Spring 的 OR 映射支持。 ApplicationContext 或 BeanFactory 內部的 OR 映射的好處是簡化了配置和部署。

  Hibernate 是 Java 平臺上一個功能全面的、開源的 OR 映射框架。Hibernate 支持開發(fā)符合常規(guī) Java 理念的持久性類 —— 包括關聯(lián)、繼承、多態(tài)、復合以及 Java 集合框架。Hibernate 查詢語言(HQL)被設計成 SQL 的一個微型面向對象擴展,它是對象和關系世界之間的橋梁。Hibernate 也支持用原始 SQL 或基于 Java 的標準和示例查詢表達查詢。Hibernate 使用 XML(*.hbm.xml) 文件把 Java 類映射到表,把 JavaBean 屬性映射到數據庫表。

  通過 JDBC 技術,支持所有的 SQL 數據庫管理系統(tǒng)。Hibernate 與所有流行的 J2EE 應用程序服務器和 Web 容器都很好地集成。

  實際示例

  一個銀行應用程序示例可以讓您自己看到 Spring AOP 和 Hibernate 一起工作有多么好。銀行帳戶用例允許用戶 (Customer) 在一個事務中打開一個或多個銀行帳戶。用戶可以申請多個銀行帳戶,可以選擇是支票帳戶類型或者是儲蓄帳戶類型。

  應用程序數據庫(Cloudscape?)容納所有客戶和帳戶信息。在這個例子中,假設在 Customer 和 Account 類之間存在 1:N 的關聯(lián)。在實際生活場景中,關聯(lián)可能需要按 m:n 建模,才能支持聯(lián)合帳戶。

  由于用戶必須可以在一個事務中申請多個帳戶,所以首先要為數據庫交互實現一個 DOA 模式。然后要設置 Spring AOP 的 TransactionProxyFactoryBean,讓它攔截方法調用并聲明性地把事務上下文應用到 DOA。

  Hibernate 實踐

  在 Spring 框架中,像 JDBC DataSource 或 Hibernate SessionFactory 這樣的資源,在應用程序上下文中可以用 bean 實現。需要訪問資源的應用程序對象只需通過 bean 引用得到這類預先定義好的實例的引用即可(這方面的更多內容在 下一節(jié)中)。在清單 1 中,可以看到示例銀行應用程序的一段摘錄:XML 應用程序上下文定義顯示了如何設置 JDBC DataSource,并在上面放一個 Hibernate SessionFactory。

  清單 1. JDBC DataSource 和 HibernateSessionFactory 連接

<!-- DataSource Property -->
<bean id="exampleDataSource"
    class="org.apache.commons.dbcp.BasicDataSource">
 <property name="driverClassName">
   <value>org.apache.derby.jdbc.EmbeddedDriver</value>
 </property>
 <property name="url">
   <value>jdbc:derby:springexample;create=true</value>
 </property>
</bean>

<!-- Database Property -->
<bean id="exampleHibernateProperties"
 class="org.springframework.beans.factory.config.PropertiesFactoryBean">
 <property name="properties">
  <props>
   <prop key="hibernate.hbm2ddl.auto">update</prop>
   <prop
    key="hibernate.dialect">net.sf.hibernate.dialect.DerbyDialect</prop>
   <prop
    key="hibernate.query.substitutions">true ‘T‘, false ‘F‘</prop>
   <prop key="hibernate.show_sql">false</prop>
   <prop key="hibernate.c3p0.minPoolSize">5</prop>
   <prop key="hibernate.c3p0.maxPoolSize">20</prop>
   <prop key="hibernate.c3p0.timeout">600</prop>
   <prop key="hibernate.c3p0.max_statement">50</prop>
   <prop
     key="hibernate.c3p0.testConnectionOnCheckout">false</prop>
  </props>
 </property>
</bean>

<!-- Hibernate SessionFactory -->
<bean id="exampleSessionFactory"
   class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
 <property name="dataSource">
     <ref local="exampleDataSource"/>
 </property>
 <property name="hibernateProperties">
     <ref bean="exampleHibernateProperties" />
 </property>
 <!--  OR mapping files. -->
 <property name="mappingResources">
    <list>
       <value>Customer.hbm.xml</value>
       <value>Account.hbm.xml</value>
    </list>
 </property>
</bean>

  清單 1 顯示了如何為示例應用程序數據庫(是 Cloudscape)配置數據源 bean (exampleDataSource)。exampleDatasource 被連接到 Spring Hibernate 的 SessionFactory。請注意 *.hbm.xml 指定了示例應用程序的 OR 映射文件。

  數據源和會話工廠設置好之后,下一步就是在 DAO 中連接,在 CustomerDAOImpl 示例中,要使用 SessionFactory。接下來,插入 Spring 的 TransactionProxyFactoryBean,它會攔截對應用程序的 CustomerDAOImpl 對象的方法調用,并聲明性地在它上面應用事務。

  清單 2. 將應用程序 DAO 和 TransactionManager 編寫在一起

<!-- Pass the session factory to our CustomerDAO -->
 <bean id="customerDAOTarget"
     class="springexample.hibernate.CustomerDAOImpl">
   <property name="sessionFactory"><ref local="exampleSessionFactory"/>
   </property>
 </bean>

  <bean id="transactionManager"
   class="org.springframework.orm.hibernate.HibernateTransactionManager">
   <property name="sessionFactory">
     <ref bean="exampleSessionFactory"/>
   </property>
  </bean>

  <bean id="userDAO"
   class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
   <property name="transactionManager"><ref local="transactionManager"/>
   </property>
   <property name="target"><ref local="customerDAOTarget"/>
   </property>
   <property name="transactionAttributes">
     <props>
       <prop key="addCustomer">PROPAGATION_REQUIRED</prop>
     </props>
  </property>
 </bean>

   在 清單 2 的這個示例中,CustomerDAOImpl 類的 addCustomer 方法是作為事務的一部分執(zhí)行的,有一個事務屬性 PROPAGATION_REQUIRED。這個屬性等價于 EJB 容器的 TX_REQUIRED。如果想讓這個方法一直在事務中運行,可以使用 PROPAGATION_REQUIRED。如果事務已經在運行,那么 bean 方法會加入事務,否則 Spring 的輕量級事務管理器會啟動一個事務。如果想在調用組件服務時總是啟動新事務,可以使用 PROPAGATION_REQUIRES_NEW 屬性。

  應用程序的連接完成之后,現在來進一步查看源代碼。

  分析這個!

  如果以前沒這么做過,那么請 下載這篇文章的源代碼。把源 zip 文件釋放到計算機中的任何位置上,例如 c:\。會創(chuàng)建一個叫作 SpringProjectPart2 的文件夾。src\spring 文件夾包含示例應用程序的 Hibernate 映射文件和 Spring 配置文件。src\springexample\hibernate 文件包含應用程序的源代碼。

  在這里會發(fā)現兩個類,即 Customer 和 Account,它們用 Hibernate 映射文件映射到兩個表。Customer 類代表客戶信息,Account 代表客戶的帳戶信息。正如前面提到的,我把這兩個類按照 1: N 關系進行建模,即一個 Customer 可以擁有多個 Account。清單 3 顯示了 Customer 對象的 Hibernate 映射文件。

  清單 3. Customer 對象的 Hibernate 映射文件

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC
         "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
         "http://hibernate./hibernate-mapping-2.0.dtd">

<hibernate-mapping>
   <class
      name="springexample.hibernate.Customer"
      table="TBL_CUSTOMER"
      dynamic-update="false"
      dynamic-insert="false">

      <id
         name="id"
         column="CUSTOMER_ID"
         type="java.lang.Long"
         unsaved-value="-1"
      >
         <generator class="native">
         </generator>
      </id>

      <set name ="accounts"
         inverse = "true"
         cascade="all-delete-orphan">
         <key column ="CUSTOMER_ID"/>
         <one-to-many class="springexample.hibernate.Account"/>

      </set>

      <property
         name="email"
         type="string"
         update="false"
         insert="true"
         column="CUSTOMER_EMAIL"
         length="82"
         not-null="true"
      />

      <property
         name="password"
         type="string"
         update="false"
         insert="true"
         column="CUSTOMER_PASSWORD"
         length="10"
         not-null="true"
      />

      <property
         name="userId"
         type="string"
         update="false"
         insert="true"
         column="CUSTOMER_USERID"
         length="12"
         not-null="true"
         unique="true"
      />

      <property
         name="firstName"
         type="string"
         update="false"
         insert="true"
         column="CUSTOMER_FIRSTNAME"
         length="25"
         not-null="true"
      />

      <property
         name="lastName"
         type="string"
         update="false"
         insert="true"
         column="CUSTOMER_LASTTNAME"
         length="25"
         not-null="true"
       />

   </class>

</hibernate-mapping>

  set name="accounts" 和一對多類標簽指定了 Customer 和 Account 之間的關系。我還在 Account.hbm.xml 文件中定義了 Account 對象的映射。

  CustomerDAOImpl.java 代表應用程序的 DAO,它在應用程序數據庫中插入客戶和帳戶信息。CustomerDAOImpl 擴展了 Spring 的 HibernateDaoSupport,它用 Spring HibernateTemplate 簡化了會話管理。這樣,可以通過 getHibernateTemplate() 方法保存或檢索數據。下面顯示的 getCustomerAccountInfo() 對 Customer 進行 查找,通過 getHibernateTemplate().find 方法用 HQL 得到客戶的帳戶信息,如清單 4 所示。

  清單 4. DAO 實現

public class CustomerDAOImpl extends HibernateDaoSupport
           implements CustomerDAO{

  public void addCustomer(Customer customer) {
    getHibernateTemplate().save(customer);
    // TODO Auto-generated method stub

  }

  public Customer getCustomerAccountInfo(Customer customer) {
    Customer cust = null;
    List list = getHibernateTemplate().find("from Customer customer " +
          "where customer.userId = ?" ,
          customer.getUserId(),Hibernate.STRING);

    if(list.size() > 0){
          cust = (Customer)  list.get(0);
    }

    return cust;

  }

  所有這些都應當很容易掌握?,F在來看代碼的實際應用!

  運行應用程序

  要運行示例應用程序,必須首先 下載 Spring 框架 和它的全部依賴文件。接下來,釋放框架到某一位置(比如 c:\ ),這會創(chuàng)建文件夾 C:\spring-framework-1.2-rc2(針對當前發(fā)行版)。在繼續(xù)之前還必須下載和釋放 Apache AntCloudscape。下載 Cloudscape 之后,把它釋放到 c:\ ,這會創(chuàng)建文件夾 C:\Cloudscape_10.0。

  接下來,釋放源代碼到 c:\ ,這會創(chuàng)建 SpringProject2 文件夾。接下來修改 build.xml 文件的入口,用實際安裝 Spring 的位置代替 C:\spring-framework-1.2-rc2,用實際安裝 Cloudscape 的位置代替 C:\Program Files\IBM\Cloudscape_10.0。

  打開命令行提示符,進入 SpringProject 目錄,在命令行提示符下輸入以下命令:build.

  這會構建并運行 CreateBankCustomerClient 類,它會創(chuàng)建 Customer 類對象,用數據填充它,創(chuàng)建 Account 對象,填充它,并把它添加到 Customer 對象。

  然后 CreateBankCustomerClient 會調用 CustomerDAOImpl.addCustomer 類,添加客戶和帳戶信息。一旦插入完成,CreateBankCustomerClient 會調用 CustomerDAOImpl.getCustomerAccountInfo 方法,根據 userid 得到客戶和帳戶信息。如果 CreateBankCustomerClient 執(zhí)行成功,會在控制臺上看到打印出 userid。也可以查詢 Cloudscape 數據庫檢索客戶和帳戶信息。

  結束語

  在三部分的 Spring 系列 的第 2 部分中,我介紹了如何集成 Spring Hibernate 和 Spring AOP。結果是一個強健的持久性框架,支持聲明性的實現事務。

  在這個系列的下一篇,也是最后一篇文章中,我將介紹 Spring 的 MVC 模塊,介紹如何用它來簡化基于 Web 的應用程序的創(chuàng)建。

  下載

  Example source code, spring files, build scripts   wa-spring2-SpringProjectPart2.zip

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多