欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
在Spring中配置Hibernate事務(wù)
在Spring中配置Hibernate事務(wù)

時(shí)間:2005-12-26
作者:Binildas Christudas
瀏覽次數: 3414
本文關(guān)鍵字:Web ServicesJavatransactionsspringhibernateEJB事務(wù)
文章工具
 推薦給朋友
 打印文章

  本文主要探討如何利用Spring來(lái)裝配組件,包括其事務(wù)上下文。從J2EE應用程序內部連接到單個(gè)的數據庫并不是什么難事。但是,如果要裝配或者集成企業(yè)級的組件,情況就復雜了。一個(gè)組件可以有一個(gè)或多個(gè)支持它的數據庫,因此,當裝配兩個(gè)或更多的組件時(shí),我們希望能夠保持在跨組件的多個(gè)數據庫中進(jìn)行的操作的原子性。J2EE服務(wù)器為這些組件提供了一個(gè)容器來(lái)保證事務(wù)原子性和跨組件獨立性。如果使用的不是J2EE服務(wù)器,則可以利用Spring來(lái)幫助我們。Spring基于Inversion of Control(控制反轉)模式(也稱(chēng)為依賴(lài)注入),它不僅可以連接組件服務(wù),還可以連接關(guān)聯(lián)的事務(wù)上下文。在本文中,我們將Hibernate用作對象/關(guān)系持久性存儲和查詢(xún)服務(wù)?! ?nbsp;

裝配組件事務(wù)
  假設在企業(yè)組件庫里,我們已經(jīng)有一個(gè)審計組件,里面有可以被客戶(hù)端調用的服務(wù)方法。然后,當我們想要構建一個(gè)訂單處理系統時(shí),我們發(fā)現存在這樣的設計要求:OrderListManager組件服務(wù)同樣需要審計組件服務(wù)。OrderListManager創(chuàng )建和管理訂單,因此所有的OrderListManager服務(wù)都有自己的事務(wù)屬性。當我們從OrderListManager服務(wù)內調用審計組件時(shí),我們實(shí)際上是在把OrderListManager服務(wù)的事務(wù)上下文傳播給審計服務(wù)。也許將來(lái)新的業(yè)務(wù)服務(wù)組件同樣需要審計組件,但那時(shí)將在一個(gè)不同的事務(wù)上下文中調用它。實(shí)際結果就是,即使審計組件的功能保持不變,它也可能是由別的業(yè)務(wù)服務(wù)功能組成,包含了混搭的(mix-and-match)事務(wù)屬性來(lái)提供不同的運行時(shí)事務(wù)性行為。

  在圖1中有兩個(gè)獨立的調用上下文流程。在流程1里,如果客戶(hù)端有TX上下文,那么OrderListManager既可以參與其中,也可以啟動(dòng)一個(gè)新的TX,這取決于客戶(hù)端是否在TX中,以及為OrderListManager方法指定了什么樣的TX屬性。這同樣適用于OrderListManager服務(wù)依次調用AuditManager方法的情況。

1 裝配組件事務(wù)

  EJB架構允許組件裝配者聲明式地給出正確的事務(wù)屬性,從而為他們提供這種靈活性。我們不探討聲明式事務(wù)管理的替代方案(即所謂的編程式事務(wù)控制),因為這會(huì )牽涉到代碼更改,從而產(chǎn)生不同的運行時(shí)事務(wù)行為。幾乎所有的J2EE應用服務(wù)器都按照X/Open XA規范提供了服從兩階段提交協(xié)議的分布式事務(wù)管理器?,F在的問(wèn)題是,我們能不能利用EJB服務(wù)器來(lái)實(shí)現相同的功能?Spring就是其中的一種解決方案。讓我們來(lái)看一下Spring如何幫助我們解決事務(wù)組裝的問(wèn)題:

使用Spring進(jìn)行事務(wù)管理
  我們將看到一個(gè)輕量級的事務(wù)基礎架構,它實(shí)際上可以管理組件級的事務(wù)裝配。Spring是其中的一個(gè)解決方案。它的優(yōu)點(diǎn)在于,我們不會(huì )被捆綁到J2EE容器服務(wù)(如JNDI DataSource)上。最棒的一點(diǎn)是,如果我們想把這個(gè)輕量級事務(wù)基礎架構關(guān)聯(lián)到一個(gè)已可用的J2EE容器基礎架構,將不會(huì )有任何問(wèn)題??雌饋?lái)我們可以利用兩者的優(yōu)點(diǎn)。

  另一方面,Spring這個(gè)輕量級事務(wù)基礎架構使用了一個(gè)面向方面編程(Aspect-Oriented Programming,AOP)框架。Spring AOP框架使用了一個(gè)支持AOP的Spring bean工廠(chǎng)。在特定于Spring的配置文件applicationContext.xml中,通過(guò)在組件服務(wù)級指定事務(wù)特性來(lái)劃分事務(wù)。

<beans><!-- other code goes here... --><bean id="orderListManager"class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><property name="transactionManager"><ref local="transactionManager1"/></property><property name="target"><ref local="orderListManagerTarget"/></property><property name="transactionAttributes"><props><prop key="getAllOrderList">PROPAGATION_REQUIRED</prop><prop key="getOrderList">PROPAGATION_REQUIRED</prop><prop key="createOrderList">PROPAGATION_REQUIRED</prop><prop key="addLineItem">PROPAGATION_REQUIRED,-com.example.exception.FacadeException</prop><prop key="getAllLineItems">PROPAGATION_REQUIRED,readOnly</prop><prop key="queryNumberOfLineItems">PROPAGATION_REQUIRED,readOnly</prop></props></property></bean></beans>

  一旦我們在服務(wù)級指定了事務(wù)屬性,org.springframework.transaction.PlatformTransactionManager接口的一個(gè)特定實(shí)現就會(huì )截獲并解釋它們。該接口如下:

public interface PlatformTransactionManager{TransactionStatus getTransaction(TransactionDefinition definition);void commit(TransactionStatus status);void rollback(TransactionStatus status);}

Hibernate事務(wù)管理器
  由于我們已決定使用Hibernate作為ORM工具,下一步要做的就是配置一個(gè)特定于Hibernate的事務(wù)管理器實(shí)現。

<beans><!-- other code goes here... --><bean id="transactionManager1"class="org.springframework.orm.hibernate.HibernateTransactionManager"><property name="sessionFactory"><ref local="sessionFactory1"/></property></bean></beans>

設計多個(gè)組件中的事務(wù)的管理
  現在,我們來(lái)討論什么是“裝配組件事務(wù)”。您也許注意到了為域中的服務(wù)級組件OrderListManager所指定的各種TX屬性。圖2所示的業(yè)務(wù)域對象模型(Business Domain Object Model,BDOM)顯示了我們的域所確定的主要對象:

2 業(yè)務(wù)域對象模型(BDOM)

  圖字:Order:訂單;Audit:審計

  為了更好的說(shuō)明,我們來(lái)列出我們的域中的一些非功能性需求(Non-Functional Requirement,NFR):

  • 業(yè)務(wù)對象需要保存在一個(gè)數據庫中(appfuse1)。
  • 審計時(shí)要登錄到另一個(gè)數據庫中(appfuse2),出于安全的考慮,數據庫要有防火墻保護。
  • 業(yè)務(wù)組件應該可以重用。
  • 必須盡一切努力審計業(yè)務(wù)服務(wù)層的所有活動(dòng)。

  考慮了以上要求之后,我們決定,OrderListManager服務(wù)會(huì )將所有的審計日志調用委托給已經(jīng)可用的AuditManager組件。這樣就得出了詳細設計,如圖3所示:

3 組件服務(wù)的設計

  這里值得注意的一點(diǎn)是,由于我們的NFR,我們要將與OrderListManager相關(guān)的對象映射到appfuse1數據庫,而將與審計相關(guān)的對象映射到appfuse2。這樣,無(wú)論要審計什么,OrderListManager組件都會(huì )調用AuditManager組件。我們會(huì )看到,OrderListManager組件中的所有方法都應該是事務(wù)性的,因為我們通過(guò)服務(wù)來(lái)創(chuàng )建訂單和線(xiàn)項目(line item)。那么AuditManager組件中的服務(wù)呢?因為它做的是審計跟蹤,我們關(guān)心的是盡可能維持長(cháng)時(shí)間的審計跟蹤,并針對系統中所有可能的業(yè)務(wù)活動(dòng)。這就產(chǎn)生了如下的需求:“即使主要的業(yè)務(wù)活動(dòng)失敗了,也要進(jìn)行審計跟蹤記錄”。AuditManager組件同樣要有自己的事務(wù),因為它也與自己的數據庫進(jìn)行交互。如下所示:

<beans><!-- other code goes here... --><bean id="auditManager"class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><property name="transactionManager"><ref local="transactionManager2"/></property><property name="target"><ref local="auditManagerTarget"/></property><property name="transactionAttributes"><props><prop key="log">PROPAGATION_REQUIRES_NEW</prop></props></property></bean></beans>

  現在,為了演示,我們把注意力放到createOrderList和addLineItem這兩個(gè)業(yè)務(wù)服務(wù)上。同時(shí)請注意,我們并沒(méi)有要求最佳設計策略——你可能注意到了,addLineItem方法拋出了FacadeException異常,而createOrderList卻沒(méi)有。在生產(chǎn)設計中,您也許希望每一個(gè)服務(wù)方法都可以處理異常場(chǎng)景。

public class OrderListManagerImplimplements OrderListManager{private AuditManager auditManager;public Long createOrderList(OrderList orderList){Long orderId = orderListDAO.createOrderList(orderList);auditManager.log(new AuditObject(ORDER + orderId, CREATE));return orderId;}public void addLineItem(Long orderId, LineItem lineItem)throws FacadeException{Long lineItemId = orderListDAO.addLineItem(orderId, lineItem);auditManager.log(new AuditObject(LINE_ITEM + lineItemId, CREATE));int numberOfLineItems = orderListDAO.queryNumberOfLineItems(orderId);if(numberOfLineItems > 2){log("Added LineItem " + lineItemId +" to Order " + orderId + ";But rolling back *** !");throw new FacadeException("Make a new Order for this line item");}else{log("Added LineItem " + lineItemId +" to Order " + orderId + ".");}}//Other code goes here...}

  為了創(chuàng )建一個(gè)異常場(chǎng)景來(lái)進(jìn)行演示,我們引入了另一種業(yè)務(wù)規則,它規定一個(gè)特定的訂單不能包含多于兩個(gè)的線(xiàn)項目?,F在應該注意,我們是從createOrderList和addLineItem中調用auditManager.log()方法的。您應該也注意到了為上述方法所指定的事務(wù)屬性。

<bean id="orderListManager"class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><property name="transactionAttributes"><props><prop key="createOrderList">PROPAGATION_REQUIRED</prop><prop key="addLineItem">PROPAGATION_REQUIRED,-com.example.exception.FacadeException</prop></props></property></bean><bean id="auditManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><property name="transactionAttributes"><props><prop key="log">PROPAGATION_REQUIRES_NEW</prop></props></property></bean>

  PROPAGATION_REQUIRED等效于TX_REQUIRED,而PROPAGATION_REQUIRES_NEW等效于EJB中的TX_REQUIRES_NEW。如果我們想讓服務(wù)方法始終在事務(wù)中運行,我們可以使用PROPAGATION_REQUIRED。當使用PROPAGATION_REQUIRED時(shí),如果已經(jīng)運行了一個(gè)TX,bean方法就會(huì )加入到該TX中;否則的話(huà),Spring的輕量級TX管理器就會(huì )啟動(dòng)一個(gè)TX。如果在調用組件服務(wù)時(shí)我們總是希望開(kāi)始新的事務(wù),那么可以利用PROPAGATION_REQUIRES_NEW屬性。

  我們還指定,當方法拋出FacadeException類(lèi)型的異常時(shí),addLineItem就總是回滾事務(wù)。這就達到了另一個(gè)粒度級別:在異常場(chǎng)景中,我們的控制可以精細到TX的具體結束方式。前綴符號“-”指定回滾TX,而前綴符號“+”指定提交TX。

  接下來(lái)的問(wèn)題是,為什么我們要為log方法設置PROPAGATION_REQUIRES_NEW屬性呢?這是由我們的以下需求決定的:無(wú)論主服務(wù)方法發(fā)生什么情況,對所有創(chuàng )建訂單以及向系統添加線(xiàn)項目的嘗試都要記錄審計跟蹤。也就是說(shuō),即使在createOrderList和addLineItem的實(shí)現過(guò)程中出現了異常也要記錄審計跟蹤。這僅在啟動(dòng)一個(gè)新的TX并在這個(gè)新的TX上下文中調用log的時(shí)候起作用。這就是為什么要為log設置PROPAGATION_REQUIRES_NEW TX屬性的原因:如果對下述方法的調用成功了

auditManager.log(new AuditObject(LINE_ITEM +lineItemId, CREATE));

  ,auditManager.log()就將在新的TX上下文中執行,而且只要auditManager.log()本身成功(即,沒(méi)有拋出異常),新的上下文就會(huì )被提交。

  設置演示環(huán)境

  準備演示環(huán)境時(shí),我參考了Spring Live這本書(shū)的流程:

  1. 下載并安裝以下組件,這時(shí)請注意使用準確的版本,不然就會(huì )引起版本不兼容問(wèn)題。
  2. 在系統中設置以下環(huán)境變量:
    • JAVA_HOME
    • CATALINA_HOME
    • ANT_HOME
  3. 把下列目錄添加到您的PATH環(huán)境變量中,或者使用完全路徑來(lái)執行腳本:
    • JAVA_HOMEin
    • CATALINA_HOMEin
    • ANT_HOMEin
  4. 要設置Tomcat,在文本編輯器中打開(kāi)/conf/tomcat-users.xml文件,驗證以下各行是否存在。如果不存在,必須手動(dòng)添加進(jìn)去:
<role rolename="manager"/><user username="admin"
password="admin" roles="manager"/> 
  1. 要創(chuàng )建基于Struts、Spring和Hibernate的Web應用程序,必須用Equinox來(lái)構建一個(gè)基本的框架程序(bare-bones starter application),它將包含預定義的文件夾結構、所有需要用到的.jar文件以及Ant構建腳本。把Equinox解壓到一個(gè)文件夾中,它將創(chuàng )建一個(gè)equinox文件夾。將目錄更改為equinox文件夾,輸入命令ANT_HOMEinnt new -Dapp.name=myusers。這樣就會(huì )創(chuàng )建一個(gè)與equinox同級的文件夾myusers。該文件夾的具體內容如下:

4 Equinoxmyusers應用程序文件夾模板

  1. 刪除myuserswebWEB-INF文件夾下的所有.xml文件。
  2. 復制equinoxxtrasstrutswebWEB-INFibstruts*.jar文件至myuserswebWEB-INFib文件夾下,這樣,這個(gè)示例應用程序就可以利用struts了。
  3. 參考資料小節的示例代碼中,解壓myusersextra.zip到一個(gè)合適的位置。將目錄更改為新創(chuàng )建的myusersextra文件夾,復制myusersextra文件夾中的所有內容,并將它們粘貼到myusers文件夾。
  4. 打開(kāi)命令提示符,將目錄轉至myusers目錄下。執行CATALINA_HOMEinstartup。要從myusers文件夾啟動(dòng)Tomcat,這一點(diǎn)非常重要,否則數據庫將不會(huì )創(chuàng )建在myusers文件夾中,從而導致在執行一些定義在build.xml中的任務(wù)時(shí)出現錯誤。
  5. 再次打開(kāi)命令提示符并將目錄轉至myusers目錄下。執行ANT_HOMEinnt install。這將構建應用程序并把它部署到Tomcat中。這時(shí),我們可以看到myusers中多了一個(gè)db目錄,以便存放數據庫appfuse1和appfuse2。
  6. 打開(kāi)瀏覽器并驗證myusers應用程序已經(jīng)部署在http://localhost:8080/myusers/上了。
  7. 要重新安裝應用程序,執行ANT_HOMEinnt remove,然后執行CATALINA_HOMEinshutdown關(guān)閉Tomcat?,F在,從CATALINA_HOMEwebapps文件夾刪除所有的myusers文件夾。然后執行CATALINA_HOMEinstartup重新啟動(dòng)Tomcat,并通過(guò)執行ANT_HOMEinnt install重新安裝應用程序。

運行演示
  為了運行測試用例,myusers estmxampleservice中提供了一個(gè)JUnit測試類(lèi),OrderListManagerTest。要執行它,可以在構建應用程序的命令提示符中輸入以下命令:

CATALINA_HOMEinnt test -Dtestcase=OrderListManager

  測試用例分為兩個(gè)主要部分:第一部分創(chuàng )建一個(gè)由兩個(gè)線(xiàn)項目組成的訂單,然后把這兩個(gè)線(xiàn)項目鏈接到訂單中。它可以成功運行,如下所示:

OrderList orderList1 = new OrderList();Long orderId1 = orderListManager.createOrderList(orderList1);log("Created OrderList with id ‘"+ orderId1 + "‘...");orderListManager.addLineItem(orderId1,lineItem1);orderListManager.addLineItem(orderId1,lineItem2);

  第二部分執行類(lèi)似的操作,但是這次我們試圖向訂單添加三個(gè)線(xiàn)項目,這將產(chǎn)生一個(gè)異常:

OrderList orderList2 = new OrderList();Long orderId2 = orderListManager.createOrderList(orderList2);log("Created OrderList with id ‘" + orderId2 + "‘...");orderListManager.addLineItem(orderId2,lineItem3);orderListManager.addLineItem(orderId2,lineItem4);//We know, we will have an exception here,still want to proceedtry{orderListManager.addLineItem(orderId2,lineItem5);}catch(FacadeException facadeException){log("ERROR : " + facadeException.getMessage());}

  控制臺的輸出如圖5所示:


5 客戶(hù)端控制臺輸出

  我們創(chuàng )建了Order1,并向其添加了兩個(gè)ID為1和2的線(xiàn)項目。然后我們創(chuàng )建Order2,并嘗試添加3個(gè)項目,前兩個(gè)(ID為3和4)添加成功,但是圖5顯示,添加第三個(gè)項目(ID為5)時(shí)業(yè)務(wù)方法遇到了異常。因此,業(yè)務(wù)方法TX被回滾,數據庫中沒(méi)有ID為5的線(xiàn)項目。從控制臺執行以下命令,就可以通過(guò)圖6和圖7進(jìn)行驗證:

CATALINA_HOMEinnt browse1

6 appfuse1數據庫中創(chuàng )建的訂單

7 appfuse1數據庫中創(chuàng )建的線(xiàn)項目

  在接下來(lái)的也是最重要的演示部分中可以看出,訂單和線(xiàn)項目保存在appfuse1數據庫中,而審計對象保存在appfuse2數據庫中。實(shí)際上,OrderListManager中的服務(wù)方法可以與多個(gè)數據庫交互。啟動(dòng)appfuse2數據庫,查看審計跟蹤,如下所示:

CATALINA_HOMEinnt browse2

8 創(chuàng )建到appfuse2數據庫中的審計跟蹤,包括失敗TX的記錄項

  表8最后一行尤其值得注意,RESOURCE列顯示這一行對應的是LineItem5。但是當我們回過(guò)來(lái)看圖7時(shí),卻發(fā)現并沒(méi)有對應于LineItem5的線(xiàn)項目。哪里出錯了呢?事實(shí)上并沒(méi)有出錯,圖7沒(méi)有的那一行其實(shí)正是這篇文章的關(guān)鍵所在,讓我們來(lái)看看是怎么回事。

  我們知道,addLineItem()方法包含PROPAGATION_REQUIRED屬性,而log()方法有PROPAGATION_REQUIRES_NEW屬性。而且addLineItem()在內部調用了log()方法。因此,當我們試圖向Order2添加第三個(gè)線(xiàn)項目時(shí),就(按照我們的業(yè)務(wù)規則)引發(fā)了異常,于是這個(gè)線(xiàn)項目的創(chuàng )建以及將其鏈接到Order2的操作都被回滾了。但是,因為還從addLineItem()中調用了log(),還因為log()具有PROPAGATION_REQUIRES_NEW TX屬性,回滾addLineItem()將不會(huì )造成回滾log(),因為log()是在一個(gè)新的TX中執行。

  讓我們對log()的TX屬性做一下改動(dòng),把PROPAGATION_REQUIRES_NEW替換為PROPAGATION_SUPPORTS。PROPAGATION_SUPPORTS屬性允許服務(wù)方法在客戶(hù)端有TX上下文時(shí)在客戶(hù)端TX中運行;如果客戶(hù)端沒(méi)有TX,就不用TX而直接運行。您可能必須重新安裝應用程序,以便數據庫中已經(jīng)可用的數據可以自動(dòng)刷新。重新安裝請按照“設置演示環(huán)境”中的步驟12進(jìn)行。

  如果再次運行,我們會(huì )發(fā)現一點(diǎn)不同。這次,在試圖向Order2添加第三個(gè)線(xiàn)項目時(shí)依然有異常,這將回滾試圖添加第三個(gè)線(xiàn)項目的事務(wù)。而這個(gè)方法又調用了log()方法。但是由于它的PROPAGATION_SUPPORTS TX屬性,log()將在與addLineItem()方法相同的TX上下文中調用。由于addLineItem()回滾,log()也回滾了,沒(méi)有留下回滾的TX的審計跟蹤。所以在圖9中沒(méi)有對應于失敗TX的審計跟蹤記錄項!

9 創(chuàng )建在appfuse2數據庫中的審計跟蹤,沒(méi)有失敗TX記錄項

  我們改動(dòng)的僅僅是Spring配置文件中的TX屬性,就產(chǎn)生了這樣不同的事務(wù)行為,如下所示:

<bean id="auditManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><property name="transactionAttributes"><props><!-- prop key="log">PROPAGATION_REQUIRES_NEW</prop --><prop key="log">PROPAGATION_SUPPORTS</prop></props></property></bean>

  這就是聲明式事務(wù)管理的效果。自從EJB出現以來(lái)我們就一直在使用這種方法,但是我們需要一個(gè)高端的應用服務(wù)器來(lái)駐留EJB組件?,F在,我們可以看到,利用Spring,沒(méi)有EJB服務(wù)器也可以達到類(lèi)似的結果。

結束語(yǔ)
  這篇文章重點(diǎn)介紹了J2EE領(lǐng)域的強大組合之一:Spring和Hibernate。利用二者的功能,現在對于容器管理持久性(Container-Managed Persistence,CMP)、容器管理關(guān)系(Container-Managed Relationships,CMR)和聲明式事務(wù)管理,我們多了一種技術(shù)選擇。雖然Spring不能視為EJB的替代方案,但是它提供的許多功能,例如普通Java對象的聲明式事務(wù)管理,使得在許多項目中沒(méi)有EJB也完全可以。

  本文的目的不是要尋找EJB的替代方案,而是為當前的問(wèn)題找出一個(gè)最可行的技術(shù)方案。至于Spring和Hibernate的輕量級組合的更多功能,就留給我們的讀者去探索了。

  參考資料

  原文出處 Wire Hibernate Transactions in Spring http://www.onjava.com/pub/a/onjava/2005/05/18/swingxactions.html

 作者簡(jiǎn)介
Binildas Christudas是工程學(xué)學(xué)士和系統學(xué)碩士,他還是Sun公司認證的Java平臺程序員、軟件開(kāi)發(fā)員和企業(yè)級的系統架構師。他有6年IT行業(yè)的從業(yè)經(jīng)驗,目前供職于一家印度IT公司 —— 塔塔咨詢(xún)服務(wù)公司,為瑞士航空、Sabena航空、新加坡航空、荷蘭皇家航空公司等提供咨詢(xún)服務(wù)。對于許多新一代航空系統的設計和開(kāi)發(fā),他的經(jīng)驗非常豐富。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
簡(jiǎn)化Spring(2)--Model層
在Spring中集成Hibernate事務(wù)
多臺電腦共用打印機的方法。
Hibernate學(xué)習之--Hibernate API之基礎篇
第三方組件FreeTextBox的使用
(原創(chuàng ))利用vs.net快速開(kāi)發(fā)windows服務(wù)(c#)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久