posts - 11,  comments - 41,  trackbacks - 0

          獲得一千萬美元風(fēng)投開始算起剛滿一年,如今SpringSource(Spring框架背后的公司)搖身一變,成為應(yīng)用服務(wù)器提供商,并且舉著SpringSource應(yīng)用平臺(SpringSource Application Platform)的黃鉞白旄對現(xiàn)有的Java EE服務(wù)器陣營發(fā)起挑戰(zhàn)。SpringSource應(yīng)用平臺是構(gòu)建在Spring、OSGi和Apache Tomcat之上的應(yīng)用服務(wù)器,這個新的應(yīng)用服務(wù)器摒棄了原有的Java EE服務(wù)器標(biāo)準(zhǔn),自然而然地將Spring編程模型展現(xiàn)其中,隨之而來的還有一套基于OSGi內(nèi)核構(gòu)建的全新部署和打包系統(tǒng)。今天是該項目在SpringSource評估許可下Beta發(fā)布版發(fā)布的重要里程碑。在隨后一個月內(nèi)會有基于開源許可(GPLv3)版本和訂閱版本的通用發(fā)布版(General Availability,GA)放出。

          SpringSource應(yīng)用平臺不是Java EE應(yīng)用服務(wù)器。盡管對于WAR部署它提供了支持,但EAR部署和其它EE的規(guī)范,如EJB等,都不在支持范圍之列。SpringSource應(yīng)用平臺被重新設(shè)計,并把關(guān)注點(diǎn)直接放在對被開源項目所廣泛使用的Spring組合的支持上。特別地,這個應(yīng)用服務(wù)器是基于Spring組合編程模型構(gòu)建的,利用Spring Dynamic Module實(shí)現(xiàn)基于OSGi的部署。SpringSource在Eclipse基金會的Equinox OSGi運(yùn)行時環(huán)境的基礎(chǔ)上創(chuàng)建了一個具備日志、跟蹤、啟動、類加載、管理和其它特性的“內(nèi)核”,Tomcat被作為一個包(bundle)納入到平臺當(dāng)中,從而實(shí)現(xiàn)對Web功能的支持。

          InfoQ借此機(jī)會對Spring框架的共同創(chuàng)始人兼SpringSource的CEO Rod Johnson進(jìn)行一次采訪,對這個新的應(yīng)用服務(wù)器展開探討。在闡釋這個新平臺的必要性時,Rod一針見血地指向目前開發(fā)和生產(chǎn)環(huán)境的許多痛處,比如跨配置文件出現(xiàn)的元數(shù)據(jù)重復(fù)現(xiàn)象,還有本質(zhì)上在項目中常常在服務(wù)器上再部署服務(wù)器(即在部署應(yīng)用時,在同一個部署單元附帶部署許多工具和框架),而與此同時這些部件卻主要只使用它們應(yīng)用服務(wù)器中的Web容器部分的事實(shí)。因此,SpringSource希望在當(dāng)今的開發(fā)需要的基礎(chǔ)上提供一個更為簡單的平臺。

          在談到這個新應(yīng)用服務(wù)器的優(yōu)點(diǎn)時,Johnson強(qiáng)調(diào)了模塊化:對于服務(wù)器本身以及提供給開發(fā)人員的打包和部署模式來說,這是個兩全之策。通過利用OSGi,以及OSGi包之間依賴關(guān)系相互作用的性質(zhì),運(yùn)行的應(yīng)用服務(wù)器只會激活在它上面運(yùn)行的應(yīng)用所需要的特性,從而削減服務(wù)器的內(nèi)存占用和啟動時間。這個依賴關(guān)系支持的功能還允許依賴類庫的多個版本共存,以支持不同應(yīng)用;因而應(yīng)用服務(wù)器的某些部分就可以很容易地更新和重啟,而無需重啟整個服務(wù)器。從開發(fā)的角度看,服務(wù)器的模塊化也使得在代碼變化時,可以很快地進(jìn)行極其細(xì)粒度的重部署。

          Johnson在言及OSGi和SpringSource對Eclipse Equinox OSGi的使用時,高度評價了OSGi規(guī)范的運(yùn)行時實(shí)現(xiàn)所帶來的基礎(chǔ)平臺,但也表示OSGi在日常的應(yīng)用開發(fā)上屬于比較底層的地位。Johnson闡述到,SpringSource希望幫助開發(fā)人員在企業(yè)環(huán)境中輕松獲得價值。在新的編程模式的構(gòu)造背后,這個新的應(yīng)用服務(wù)器將OSGi的許多復(fù)雜性抽象了出來。Johnson接著說,應(yīng)用服務(wù)器將會支持PAR,一套新的可部署單元,簡化企業(yè)應(yīng)用在使用OSGi上的復(fù)雜性(下文會詳細(xì)說明)。

          當(dāng)被問到對于沒有對OSGi提供原生支持的遺留類庫的支持時,Johnson回應(yīng)到,他們已經(jīng)在上面花費(fèi)了很大心血,使得應(yīng)用服務(wù)器環(huán)境和類加載功能能夠以兼容的方式和遺留類庫協(xié)作。

          當(dāng)被問到對不提供OSGi原生支持的類庫的遺留支持時,Johnson回答說他們已經(jīng)在這方面投入了大量精力,保證應(yīng)用服務(wù)器環(huán)境和類加載功能可以和遺留類庫兼容工作。SpringSource還會為他們在如Tomcat之類的項目上所做的任何變更給這些項目提交補(bǔ)丁,使這些類庫可以和OSGi包兼容。

          Johnson解釋到,應(yīng)用服務(wù)器的主題代碼將在GPL v3的許可證下發(fā)布。開發(fā)人員在服務(wù)器、編程模式和部署單元上要接觸到的所有部分都會以開源的形式提供。SpringSource還將提供應(yīng)用服務(wù)器的商業(yè)版本,包括支持、保障、管理和監(jiān)控的功能。


          談到Spring應(yīng)用平臺發(fā)布之后對Spring組合繼續(xù)支持JavaEE有什么影響,Johnson回答說:

          ……我們從根本上說并不打算把Spring用戶社區(qū)驅(qū)趕到任何方向。我們僅僅是給用戶另一種選擇。Spring的哲學(xué)是用戶總是正確的。用戶是聰明的,他們完全明白自己的需要。不管用戶是否選擇SpringSource應(yīng)用平臺,我們覺得用戶總會歡迎多一點(diǎn)選擇的……

          Johnson保證SpringSource一定會繼續(xù)確保Spring組合以及其他SpringSource產(chǎn)品兼容于其它應(yīng)用平臺。接著Johnson還評論了即將到來的Java EE 6規(guī)范:

          Java EE 6重點(diǎn)在模塊性,這個方向是正確的。很可能SpringSource應(yīng)用服務(wù)器會在一定程度上符合Java EE 6。Java EE 6分成A、B、C三種規(guī)格(profile)。我們幾乎肯定會實(shí)現(xiàn)A和B規(guī)格,C規(guī)格里面我非常確定將實(shí)現(xiàn)Entity Beans 1.1模型以及一些遺留技術(shù)。我還不能說是100%確定,因?yàn)镴ava EE 6規(guī)范還沒有定案。

          最后,InfoQ和Johnson討論到了SpringSource應(yīng)用平臺的大局方面。對于轉(zhuǎn)換到OSGi,他的回答是:

          傳統(tǒng)的應(yīng)用服務(wù)器模型正逐漸過時。BEA和IBM正在用OSGi逐步重新實(shí)現(xiàn)他們的應(yīng)用服務(wù)器。 SpringSource現(xiàn)在就提供OSGi支持。從統(tǒng)計數(shù)字上看,大多數(shù)人都不會部署到完整的平臺上,他們部署到Tomcat。他們選擇了Spring 編程模型而非Java EE。市場已經(jīng)作出了選擇,問題只是開發(fā)者還要和服務(wù)器斗爭多長時間。

          Johnson解釋說他對SpringSource應(yīng)用平臺成功的自信來自三個原因:

          • 它是第一個建立在現(xiàn)代技術(shù)基礎(chǔ)上的產(chǎn)品。符合Java EE規(guī)范已經(jīng)不是至高無上的目標(biāo)。干凈的代碼基礎(chǔ)是我們的一項競爭優(yōu)勢。我們在設(shè)計和實(shí)現(xiàn)中滿足的是現(xiàn)今的需求,而不是10年前的需求。
          • POJO編程是現(xiàn)在行業(yè)的方向所在。過去POJO編程是被強(qiáng)行嫁接到其它產(chǎn)品上的。在我們的產(chǎn)品中,POJO編程是設(shè)計的前提。
          • SpringSource應(yīng)用平臺采用的OSGi技術(shù)是下一代技術(shù)的基礎(chǔ)。

          除了Rod Johnson,InfoQ還與SpringSource的Rob Harrop探討了新應(yīng)用服務(wù)器的一些技術(shù)細(xì)節(jié)。對于與傳統(tǒng)Java EE應(yīng)用服務(wù)器相比有何增減,他說:

          ……JPA和JMS都支持,但我們沒有包含任何特定實(shí)現(xiàn)。對于JPA,我們支持Hibernate、 OpenJPA和Toplink。我們在OSGi環(huán)境中增加了對加載時織入的支持,而且會尊重應(yīng)用的邊界,因此不會意外污染應(yīng)用間共享的庫。不包括 JNDI,我們用OSGi Service Registry來取代它。Servlets是通過內(nèi)嵌的Tomcat來支持的。JEE中有而SpringSource應(yīng)用平臺沒有的東西包括 Entity Beans等等。

          接下來InfoQ問到Spring Dynamic Modules。Spring DM成為公開項目已經(jīng)有一段時間了。對于模塊化部署,我們向Harrop詢問Spring DM是否增加了什么新東西:

          這個平臺引入了應(yīng)用的概念,應(yīng)用由一個或多個Bundle組成。應(yīng)用中的包有明確的作用域,可以防止發(fā)生應(yīng)用間的沖突。在應(yīng)用把服務(wù)發(fā)布到OSGi service registry的情況下,防止沖突尤其重要,誰也不想見到服務(wù)之間發(fā)生沖突。

          我們引入了Import-Library語句,因此在應(yīng)用中使用第三方庫變得更加簡單。你不需要再寫一大串不直觀的 Import-Package聲明,Import-Library可以自動為指定的庫引入所有必需的package。像Hibernate JPA這樣的庫還可以跨多個Bundle,可見Import-Library確實(shí)物有所值。

          至于為了讓Spring DM在平臺中運(yùn)行而進(jìn)行的擴(kuò)展,為數(shù)不多。

          Harrop接下來說明了新的PAR格式:

          Spring DM掌控下的Bundle(Spring DM powered bundles)是包含META-INF/spring/*.xml文件的普通OSG Bundle。Bundle啟動的時候META-INF/spring/*.xml文件會自動成為該Bundle的 ApplicationContext。Spring DM提供了一種機(jī)制讓各Bundle通過Spring NamespaceHandler導(dǎo)入和導(dǎo)出服務(wù)。

          一個PAR(Platform ARchive)本質(zhì)上是一組OSGi Bundle,通常其中有一部分是在Spring DM掌控下的。這些Bundle共同組成了一個邏輯上的應(yīng)用。編程的時候完全是純粹的OSGi、Spring和Spring DM——PAR沒有改變什么。

          以前一般用Buddy Classloaders之類的技術(shù)來解決遺留/非OSGi庫的問題,SpringSource這次是怎么做的呢?Rob回答說:

          簡單來說我們避免做這樣的事。Buddy類裝載、動態(tài)import、require-bundle,這些我們都明確回避,因?yàn)榫S持一致的類空間太困難了。我們也不會提供任何專有的替代機(jī)制。

          相反,我們給Equinox增加了一些低級的鉤子,以實(shí)現(xiàn)典型的場景下的資源裝載。我們擴(kuò)展了類裝載來支持加載時織入,并且把裝載語義丟到一邊。我們操縱context classloader,讓第三方一如既往地看到類。PAR是其中的核心角色,因?yàn)樗x了上下文類裝載以及加載時織入的可見范圍。

          對于一些最糟糕的情況,我們會提供修補(bǔ)版的庫,讓它們能在OSGi中工作。修補(bǔ)版的庫可以通過SpringSource Enterprise Bundle Repository獲得,我們的修改也會提交回相應(yīng)的項目。

          最后Harrrop著重強(qiáng)調(diào)了這個應(yīng)用服務(wù)器在模塊化上的優(yōu)勢,應(yīng)用服務(wù)器因此可以維持最低的內(nèi)存占用。平臺在運(yùn)行中才設(shè)置依賴項,因此只有確實(shí)用到的依賴項才會被裝載。

          最近幾年中有過許多關(guān)于Java EE標(biāo)準(zhǔn)是否已經(jīng)死亡的討論,而今天我們看到一個可能很重要的應(yīng)用服務(wù)器不帶Java EE支持。這種變化對于未來有何影響?你怎么看?


          轉(zhuǎn)載自:InfoQ中文站 http://www.infoq.com/cn/
          posted @ 2008-05-01 20:37 GoKu 閱讀(1773) | 評論 (2)編輯 收藏

          雖然現(xiàn)在出現(xiàn)了很多ORM框架,可是還是有很多朋友也許還在使用JDBC,就像我現(xiàn)在一樣,除了學(xué)習(xí)的時候在使用Hibernate、Spring類似這些優(yōu)秀的框架,工作時一直都在使用JDBC。本文就簡單介紹一下利用Jakarta Commons旗下beanutils、dbutils簡化JDBC數(shù)據(jù)庫操作,以拋磚引玉,希望對像我一樣在使用JDBC的朋友有所幫助。

              下面就分兩部分簡單介紹beanutils、dbutils在基于JDBC API數(shù)據(jù)庫存取操作中的運(yùn)用。第一部分顯介紹beanutils在JDBC數(shù)據(jù)庫存取操作中的運(yùn)用,第二部分介紹dbutils在JDBC數(shù)據(jù)庫存取操作中的運(yùn)用,最后看看他們的優(yōu)缺點(diǎn),談?wù)劚救嗽陧椖窟\(yùn)用過程中對他們的一點(diǎn)心得體會,僅供參考,其中有錯誤的地方希望大蝦不吝賜教,大家多多交流共同進(jìn)步。

          一、Jakarta Commons beanutils

                 Beanutils是操作Bean的銳利武器,其提過的BeanUtils工具類可以簡單方便的讀取或設(shè)置Bean的屬性,利用Dyna系列,還可以在運(yùn)行期創(chuàng)建Bean,符合懶人的習(xí)慣,正如LazyDynaBean,LazyDynaClass一樣,呵呵。這些用法已經(jīng)有很多文章提及,也可以參考apache的官方文檔。

          對于直接利用JDBC API訪問數(shù)據(jù)庫時(這里針對的是返回結(jié)果集ResultSet的查詢select),大多數(shù)都是采用兩種方式,一種是取出返回的結(jié)果集的數(shù)據(jù)存于Map中,另一種方式是Bean里。針對第二種方式,Beanutils里提供了ResultSetDynaClass結(jié)合DynaBean以及RowSetDynaClass結(jié)合DynaBean來簡化操作。下面用以個簡單的例子展示一下beanutils的這兩個類在JDBC數(shù)據(jù)庫操作中的運(yùn)用。

          請在本機(jī)建立數(shù)據(jù)庫publish,我用的是MySQL,在publish數(shù)據(jù)庫中建立表book,腳本如下:
          CREATE TABLE book(
            id int(11) NOT NULL auto_increment,
            title varchar(50) character set latin1 NOT NULL,
            authors varchar(50) character set latin1 default NULL, 
            PRIMARY KEY  (id)


                   然后用你喜歡的編輯器建立一個類BeanutilsJDBCTest,我們先用ResultSetDynaClass來處理,然后再用RowSetDynaClass來實(shí)現(xiàn)同樣的類,之后看看他們之間有什么不同,用ResultSetDynaClass處理的源代碼如下所示:

          package cn.qtone.test;

          import java.sql.Connection;
          import java.sql.DriverManager;
          import java.sql.ResultSet;
          import java.sql.Statement;
          import java.util.Iterator; 
          import org.apache.commons.beanutils.DynaBean;
          import org.apache.commons.beanutils.PropertyUtils;
          import org.apache.commons.beanutils.ResultSetDynaClass; 

          public class BeanutilsJDBCTest{
                 public static void main(String[] args) {
                        Connection con = null;
                        Statement st = null;
                        ResultSet rs = null;
                        try {
                               Class.forName("com.mysql.jdbc.Driver");

                               String url = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";

                               con = DriverManager.getConnection(url, "root", "hyys");

                               st = con.createStatement();

                               rs = st.executeQuery("select * from book");

                               ResultSetDynaClass rsDynaClass = new ResultSetDynaClass(rs);

                               Iterator itr = rsDynaClass.iterator();

                               System.out.println("title-------------authors");

                               while (itr.hasNext()) {
                                      DynaBean dBean = (DynaBean) itr.next();
                                      System.out.println(PropertyUtils.getSimpleProperty(dBean,"title")
                                                    + "-------------"+ PropertyUtils.getSimpleProperty(dBean, "authors"));

                               }
                        } catch (Exception e) {
                               e.printStackTrace();
                        } finally {
                               try {
                                      if (rs != null) {
                                             rs.close();
                                      }
                                      if (st != null) {
                                             st.close();
                                      }
                                      if (con != null) {
                                             con.close();
                                      }
                               } catch (Exception e) {
                                      e.printStackTrace();
                               }
                        }
                 }




          用RowSetDynaClass處理的源代碼如下所示: 


          package cn.qtone.test; 

          import java.sql.Connection;
          import java.sql.DriverManager;
          import java.sql.ResultSet;
          import java.sql.Statement;
          import java.util.Iterator;
          import java.util.List; 
          import org.apache.commons.beanutils.DynaBean;
          import org.apache.commons.beanutils.PropertyUtils;
          import org.apache.commons.beanutils.RowSetDynaClass; 

          public class BeanutilsJDBCTest{
                 public static void main(String[] args) {
                        List rsDynaClass = rsTest();

                        System.out.println("title ------------- authors ");

                        Iterator itr = rsDynaClass.iterator();

                        while (itr.hasNext()) {

                               DynaBean dBean = (DynaBean) itr.next();

                               try {
                                      System.out.println(PropertyUtils.getSimpleProperty(dBean,"name")
                                                    + "-------------"+ PropertyUtils.getSimpleProperty(dBean, "mobile"));

                               } catch (Exception e) {
                                      // TODO 自動生成 catch 塊
                                      e.printStackTrace();
                               }
                        }
                 } 

                 private static List rsTest() {

                        Connection con = null;
                        Statement st = null;
                        ResultSet rs = null;

                        try {
                               Class.forName("com.mysql.jdbc.Driver");

                               String url = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";

                               con = DriverManager.getConnection(url, "root", "hyys");

                               st = con.createStatement();

                               rs = st.executeQuery("select * from book");

                               RowSetDynaClass rsdc = new RowSetDynaClass(rs);

                               return rsdc.getRows();

                        } catch (Exception e) {
                               e.printStackTrace();
                        } finally {
                               try {
                                      if (rs != null) {
                                             rs.close();
                                      }
                                      if (st != null) {
                                             st.close();
                                      }
                                      if (con != null) {
                                             con.close();
                                      }
                               } catch (Exception e) {
                                      e.printStackTrace();
                               }
                        }

                        return null;
                 }



          這兩個方法輸出的結(jié)果應(yīng)該是一樣的。但是很顯然第二種方式比第一種方式要好,它把數(shù)據(jù)訪問部分抽取出來放到一個方法中,顯得簡單清晰。

          其實(shí)在利用ResultSetDynaClass時,必須在ResultSet等數(shù)據(jù)庫資源關(guān)閉之前,處理好那些數(shù)據(jù),你不能在資源關(guān)閉之后使用DynaBean,否則就會拋出異常,異常就是說不能在ResultSet之后存取數(shù)據(jù)(具體的異常名我也忘了),當(dāng)然你也可以采用以前的方式一個一個的把數(shù)據(jù)放到Map里,如果你一定要那樣做,建議還是別用Beanutils,因?yàn)檫@沒帶給你什么好處??傊肦esultSetDynaClass你的程序的擴(kuò)展性非常部好。

          從第二中方式可以看出,利用RowSetDynaClass可以很好的解決上述ResultSetDynaClass遇到的問題,RowSetDynaClass的getRows()方法,把每一行封裝在一個DynaBean對象里,然后,把說有的行放到一個List里,之后你就可以對返回的List里的每一個DynaBean進(jìn)行處理,此外對于DynaBean你還可以采用標(biāo)準(zhǔn)的get/set方式處理,當(dāng)然你也可以用PropertyUtils. getSimpleProperty(Object bean, String name)進(jìn)行處理。

          從上面的分析中,你應(yīng)該可以決定你應(yīng)該使用ResultSetDynaClass還是RowSetDynaClass了。





          未完待續(xù)……

          =============================

          二、Jakarta Commons dbutils:
              用JDBC API時最令人討厭的就是異常處理,也很煩瑣,而且很容易出錯,本人曾考慮過利用模板進(jìn)行處理,后來看到了dbutils,之后就采用那個dbutils,采用模板的方式各位朋友可以參考Spring,Spring的JdbcTemplate不靈活而強(qiáng)大,呵呵,說句閑話,實(shí)在太佩服Rod Johnson了,Rod Johnson真的很令人尊敬。
              Dbutils的QueryRunner把大多數(shù)與關(guān)閉資源相關(guān)的封裝起來,另外,你也可以使用DbUtils進(jìn)行關(guān)閉,當(dāng)然DbUtils提供的功能當(dāng)然不止這些,它提過了幾個常用的靜態(tài)方法,除了上述的關(guān)閉資源外,DbUtils. commitAndClose(Connection conn)還提供事務(wù)提及等操作。
          還是以一個例子來說說吧,畢竟我不是搞業(yè)務(wù)的,小嘴巴吧嗒吧噠不起來啊,呵呵。
              為了和采用Beanutils更好的進(jìn)行對比,這個例子還是實(shí)現(xiàn)同樣的功能,數(shù)據(jù)庫同樣采用前一篇文章中提到的publish。
          同樣的,用你喜歡的編輯器建立一個類DbutilsJDBCTest,示例代碼如下所示:
          package cn.qtone.test;
          import java.sql.Connection;
          import java.sql.DriverManager;
          import java.sql.SQLException;
          import java.util.List;
          import java.util.Map;
          import org.apache.commons.dbutils.DbUtils;
          import org.apache.commons.dbutils.QueryRunner;
          import org.apache.commons.dbutils.handlers.MapListHandler;
          public class DbutilsJDBCTest{
              public static void main(String[] args) {
                  Connection conn = null;
                  String jdbcURL = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";
                  String jdbcDriver = "com.mysql.jdbc.Driver";
                  try {
                      DbUtils.loadDriver(jdbcDriver);
                      // Username "root". Password "root"
                      conn = DriverManager.getConnection(jdbcURL, "root", "root");
                      QueryRunner qRunner = new QueryRunner();
                      System.out.println("***Using MapListHandler***");
                      //以下部分代碼采用Map存儲方式,可以采用Bean的方式代替進(jìn)行處理
                      List lMap = (List) qRunner.query(conn,
                              "select title,authors  from books", new MapListHandler());
                      //以下是處理代碼,可以抽取出來
          System.out.println("title ------------- authors ");
                          for (int i = 0; i < lMap.size(); i++) {
                                  Map vals = (Map) lMap.get(i);
                                  System.out.println(vals.get("title")+"-------------"+ vals.get("authors"));
                          }
                  } catch (SQLException ex) {
                      ex.printStackTrace();
                  } finally {
                      DbUtils.closeQuietly(conn);
                  }
              }
          }

          怎么樣?是不是比采用Beanutils的ResultSetDynaTrial和RowSetDynaClass好多了?采用Beanutils令人難纏的是關(guān)閉那些資源以及處理那些異常,而這里采用Dbutils顯然代碼量減少了很多。
          上例在處理結(jié)果集時,它把數(shù)據(jù)庫中的每一行映射成一個Map,其中列名作為Key,該列對應(yīng)的值作為Value存放,查詢的所有的數(shù)據(jù)一起放在一個List里,然后進(jìn)行處理,當(dāng)然,一個更明智的處理是直接返回List然后再單獨(dú)進(jìn)行處理。
          事實(shí)上上例返回的結(jié)果集中的每一行不必放在一個Map里,你可以放在一個Bean里,當(dāng)然如果你真的很懶,你也可以使用Beanutils的LazyDynaClass和LazyDynaBean,不過也許沒有必要那么做,至于原因請看下文。

          如果使用Bean而不是用Map,那么,你也許需要建立一個Bean,如下:
          package cn.qtone.test;
          public class Book {
              public int id;
              public String title;
              public String authors ;
              public StudentBean() {
              }
              public String getAuthors() {
                  return authors;
              }
              public void setAuthors(String authors) {
                  this.authors = authors;
              }
              public int getId() {
                  return id;
              }
              public void setId(int id) {
                  this.id = id;
              }
              public String getTitle() {
                  return title;
              }
              public void setTitle(String title) {
                  this.title = title;
              }
          }

          然后簡單修改一下DbutilsJDBCTest 中的部分代碼即可,代替之后的源代碼如下:

          package cn.qtone.test;

          import java.sql.Connection;
          import java.sql.DriverManager;
          import java.sql.SQLException;
          import java.util.List;
          import java.util.Map;
          import org.apache.commons.dbutils.DbUtils;
          import org.apache.commons.dbutils.QueryRunner;
          import org.apache.commons.dbutils.handlers.BeanListHandler;

          public class DbutilsJDBCTest{
              public static void main(String[] args) {
                  Connection conn = null;
                  String jdbcURL = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";
                  String jdbcDriver = "com.mysql.jdbc.Driver";
                  try {
                      DbUtils.loadDriver(jdbcDriver);
                      // Username "root". Password "root"
                      conn = DriverManager.getConnection(jdbcURL, "root", "root");
                      QueryRunner qRunner = new QueryRunner();
                      System.out.println("***Using BeanListHandler ***");
                      //以下部分代碼采用Map存儲方式,可以采用Bean的方式代替進(jìn)行處理
          List lBeans = (List) qRunner.query(conn," select title,authors from books ", new BeanListHandler(Book.class));
              //以下是處理代碼,可以抽取出來
          System.out.println("title ------------- authors ");
              for (int i = 0; i < lBeans.size(); i++) {
                      Book vals = (Book) lBeans.get(i);    
                    System.out.println(vals.getTitle ()+"-------------"+ vals. getAuthors ());
                          }
                  } catch (SQLException ex) {
                      ex.printStackTrace();
                  } finally {
                      DbUtils.closeQuietly(conn);
                  }
              }
          }
              這兩種法輸出的結(jié)果應(yīng)該是一樣的。兩種處理方式都差不多,但我更愿意采用第一種,因?yàn)榈谝环N少寫一個bean,而且我測試過采用Map的方式即第一種方式性能要好的多,采用Bean性能比較低可能是因?yàn)椴捎梅瓷涞木壒?,采用反射的東東性能和不采用反射的還是有點(diǎn)差距。也是這個原因,不推薦采用LazyDynaClass和LazyDynaBean,因?yàn)椴捎眠@二者是在運(yùn)行期動態(tài)創(chuàng)建Bean類和Bean屬性,然后再創(chuàng)建Bean對象的,其性能可想而知了(不過我沒有測試過啊,所以我說這個話可說是沒有根據(jù)的,感興趣的朋友自己測試一下,記得告訴我結(jié)果哦,呵呵),除了MapListHandler以及BeanListHandler之外,DButils還提供了其他的Handler,如果這些不能滿足你的需求,你也可以自己實(shí)現(xiàn)一個Handler。
              最后,也是最大的體會,也許是最大的收獲吧,那就是:對于每一個項目,在根據(jù)每一個需求獲取相應(yīng)解決方案時,先尋找開源組件,看是否已經(jīng)有滿足某些功能需求的開源組件,如果沒有,再考慮自主開發(fā)或者向第三方購買,否則盡量采用開源組件.
              請盡量享用開源的魅力,盡情的擁抱開源吧。

          posted @ 2008-04-24 16:39 GoKu 閱讀(778) | 評論 (0)編輯 收藏
          僅列出標(biāo)題
          共2頁: 上一頁 1 2 

          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          常用鏈接

          留言簿(1)

          隨筆檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 南宫市| 贵港市| 巴南区| 兴和县| 兴山县| 武穴市| 吉木萨尔县| 长垣县| 丰都县| 福泉市| 喀喇| 余江县| 鄄城县| 昌邑市| 山东省| 若尔盖县| 玉门市| 昭通市| 广宁县| 兴国县| 景宁| 若尔盖县| 凤凰县| 仪征市| 涿鹿县| 开阳县| 佛冈县| 旌德县| 拉孜县| 磐石市| 墨脱县| 洪洞县| 岳西县| 江川县| 延寿县| 长泰县| 武穴市| 竹山县| 阳山县| 上林县| 海口市|