隨筆-20  評論-2  文章-0  trackbacks-0
           

          【第一篇】

          我是如何提高口語水平的?


             首先、確定你自己的英語水平。中國大學(xué)畢業(yè)生的通病是,書面閱讀還可以,口語不行,聽力很差,書寫湊合。但每個(gè)人具體情況又都不一樣,有人閱讀專業(yè)書一目 十行,但讀報(bào)紙很費(fèi)勁。有人聽新聞可以,聽別的不行。你必須首先了解自己,然后針對你的情況對癥下藥。這種評估工作最好找英語好的人幫你做,如果不方便, 只能自己評自己,就要盡量做到客觀。

            其次、確定自己的發(fā)音水平。我有個(gè)朋友對我說他的發(fā)音沒問題,可實(shí)際上他說得很多詞我都聽不懂。你學(xué)的是英國音還 是美國音都無所謂,反正最終從你嘴里出來的肯定是中國音。最重要的是發(fā)音要合理。英語每一個(gè)單詞都有自己的念法,你不能憑空想象。比如,有人把 RESUME讀做RE-'SOOM,這樣,別人說RE-SIU-'MAY,你不知道是什么。你念RE-'SOOM,別人也聽不懂。再次、確定自己的英語學(xué) 習(xí)目標(biāo)。我這里僅把口語交流做為目標(biāo)。最后、開始學(xué)習(xí)。

          1、口語學(xué)習(xí)的關(guān)鍵是要模仿人家的說話。這包括語音和語調(diào)兩部分。中國英語教學(xué)重視語調(diào)的很少,盡管很多時(shí)候語調(diào)可能比語音更重要。

          2、買一臺錄音機(jī),找一合磁帶。根據(jù)你的水平,可以選擇新概念第二或第三冊,也可以到圖書館借一套有書和磁帶的小故事集。注意:一定要有書,故事篇幅不能太長,生詞量要小,過于簡單沒有關(guān)系。我傾向于使用故事,而不是對話或新聞聽力材料。

          3、進(jìn)行跟讀訓(xùn)練。放磁帶,看著書,搞明白每一個(gè)單詞的意思,理解整個(gè)故事情節(jié)。然后,放一句,暫停,學(xué)著人家讀一句,然后,放下一句,暫停,再學(xué)一句,繼續(xù)。

          4、跟讀過程中要注意的幾點(diǎn):

          (1)一定要盡力模仿發(fā)音和語調(diào),越象越好。

          (2)開始時(shí)速度可以比較慢,要逐步使自己跟上人家的速度。

          (3)中間可以回倒重放,但我傾向于讓大家完成一小段后再回去重來。

          5、同步閱讀。當(dāng)你對文章發(fā)音、語調(diào)完全掌握之后,就要在放錄音的同時(shí)同步跟讀。爭取讓自己的聲音與他完全重合。注意語調(diào)和語音。如果中間有結(jié)巴的地方也不要緊,繼續(xù)讀下去,然后再回來重讀。

          6、關(guān)掉錄音機(jī),朗誦課文。注意使用學(xué)到的語音語調(diào)。帶滾瓜爛熟之后,可以進(jìn)入下一篇課文。

            這樣,一兩個(gè)月之后,當(dāng)你“精讀”過五到十篇約一千字篇幅的文章之后,你會發(fā)現(xiàn)你的英語發(fā)音和聽力有了明顯的進(jìn)步。再配合其他學(xué)習(xí),如與人聊天,看電視,聽廣播,等等,口語水平會得到顯著提高。

          【第二篇】

                   英語作為一種工具,其實(shí)用性愈顯重要。傳統(tǒng)英語教育方法由于過于艱深化,以及盲目的應(yīng)試模式使大部分的英語學(xué)習(xí)者學(xué)了幾年甚至數(shù)十年,卻仍然處于聽不懂開不了口的尷尬境地。那么究竟如何才能在比較短的時(shí)間里快速提高口語水平,讓她真正為你所用呢?
             西方最新流行一種外語學(xué)習(xí)理論,即口語提高的最好方式就是采用短期突破法。從下面的公式中,就可以看出,口語短期突破的方法是很有效的。
            口語提高速度定律=說英語時(shí)間/說中文時(shí)間Speed of learning English=Speaking English/Speaking Chinese ( in a period of time)
            比如,在給定的一天時(shí)間內(nèi)(16小時(shí)),學(xué)生A練習(xí)英語口語的時(shí)間為14小時(shí),說中文的時(shí)間為2小時(shí),兩者的比例為7:1;學(xué)生B練習(xí)口語的時(shí)間為2 小時(shí)英語,說中文的時(shí)間為14小時(shí)。比例為1:7。如此一來,學(xué)生A比學(xué)生B說英語的比例大49倍。
            我們認(rèn)為:這一理論其實(shí)就是對語言學(xué)習(xí)規(guī)律一次很好的回歸,語言的核心是使用者能夠隨時(shí)隨地地使用它。你用的時(shí)間越長,你就越熟練,這里我們說的使用 就是“說”,用嘴巴表達(dá)出來,而不是用眼睛和腦子去看和死記。如果你能夠在一段時(shí)間內(nèi)的大部分時(shí)間里堅(jiān)持持續(xù)使用英語而不是中文進(jìn)行表達(dá),把學(xué)習(xí)英語的任 務(wù)轉(zhuǎn)化成母語似的說話習(xí)慣,你就完全可以在很短的時(shí)間內(nèi)有效掌握一口流利的英語口語。
            當(dāng)然現(xiàn)實(shí)情況卻是:很多人并沒有這樣的勇氣和能力去堅(jiān)持使用一個(gè)完全不熟悉的語言進(jìn)行日常的交流!所以選用一套優(yōu)秀的教材和相應(yīng)的工具就顯得異常重要了,這種教材應(yīng)該具備以下特點(diǎn)才能幫助你克服困難:
            1、能夠隨時(shí)隨地學(xué)習(xí),讓你很容易就接觸到英語;
            2、能夠讓你脫離書本,完全浸在英語環(huán)境里;
            3、內(nèi)容應(yīng)該精挑細(xì)選,具備典型性和代表性,幫助你在短時(shí)間內(nèi)掌握精華內(nèi)容,從而建立起長期學(xué)習(xí)的信心和基本能力。
            同時(shí)你應(yīng)該注意培養(yǎng)自己的自信,學(xué)會勇敢犯錯(cuò)誤,克服恐懼的心理障礙。其實(shí)這種心理障礙是成人自己加給自己的,為什么我們小時(shí)候?qū)W母語這么自然容易,就是因?yàn)槟莻€(gè)時(shí)候不知道什么是丟臉。所以我們應(yīng)該象小時(shí)候那樣暫時(shí)忘卻丟臉,勇敢地去丟臉!

          【第三篇】

          想提高英語口語水平,首先要在語音上下功夫:)~
          下面是些方法,你可以根據(jù)自己的學(xué)習(xí)方式掌握:)~

          1.其次,要有大量的閱讀和聽力做基礎(chǔ)。在讀和聽的過程中,積累了詞匯,掌握了句型,熟悉了用英語表達(dá)思想的方式,最重要的是培養(yǎng)了語感。

          2.同時(shí),學(xué)英語口語也需要用多種辦法:如大聲朗讀英語對話和文章,朗讀各種句型的例句和口語中最常用的句子,背誦文章及演講,與會英語的人練口語,當(dāng) 然,最好與以英語為母語的人練口語。事實(shí)上,自言自語亦是練習(xí)口語的有效的方法之一。如果你把自己說的英語給錄制下來,聽聽自己的錄音,若有問題,再加以 改正,效果就會更好。

          3.說英語還要有膽量。如果你能在說不太出口,或是說不好的情況下,大膽地說。說上一段時(shí)間后,突然有一天你會自如、清楚地表達(dá)自己的思想。有了大膽說的精神,你才能闖過口語的難關(guān)。

          4.只會學(xué)英語,而不能盡快地去用,那就永遠(yuǎn)也學(xué)不好英語。在學(xué)英語的過程中,要始終尋找機(jī)會說英語。比如說,你周圍有幾個(gè)喜歡說英語的朋友,大家在一起 就要用英語來交談。這種交談有利于每個(gè)人的英語學(xué)習(xí),因?yàn)榇蠹叶加袡C(jī)會運(yùn)用自己已掌握的英語知識來交流思想,鞏固了已學(xué)的知識,并把知識轉(zhuǎn)化成技能,同 時(shí),還能從別人那兒學(xué)到新的東西。要想學(xué)好英語口語就要多說。

          5.能同以英語為母語的人說英語是最佳方法。在國內(nèi)學(xué)英語缺乏環(huán)境,看電影學(xué)英語口語是彌補(bǔ)環(huán)境不足的好方法。英語電影是一部英語國家的生活、文化、風(fēng)俗 等一切的百科全書,是最全的英語口語百科全書。大量地看英文電影就是你徹底攻克英語“聽”和“說”的法寶。英語電影把你帶入了一個(gè)新的世界中去。你在電影 中,學(xué)到了英語口語的語匯、短語、句子結(jié)構(gòu),以及表達(dá)各種內(nèi)容的說法。你要做的就是把自己想像成電影中的一個(gè)角色,在經(jīng)歷著自己的生活,又在經(jīng)歷著其他人 的生活。總之,看一部電影比在美國生活一天還好,看電影也能學(xué)到地道的英語口語。

          【第四篇】

          當(dāng)代社會是個(gè)開放社會,信息社會,人們越來越重視交際,而我國改革開放的成功也日益提高了我國在世界上的地位,我們與世界各國交流的領(lǐng)域越來越廣了,沒有出眾的英語口語表達(dá)將會寸步難行。
            而要提高英語口語表達(dá)能力,就要先了解英語口語表達(dá)的過程是怎樣發(fā)生的。大家知道,語言是思維的外殼。口語表達(dá)的過程,實(shí)際上是一個(gè)復(fù)雜的心理和生理過程,是思維借助詞語按一定句式迅速轉(zhuǎn)換為有聲言語的過程。因此,口語能力的強(qiáng)弱取決于:
            1、思維能力的強(qiáng)弱,特別是與口語有關(guān)的思維的條理性、敏銳性與靈活性,這是關(guān)鍵。
            2、準(zhǔn)確、迅速地組織言語(選詞、造句、組段、構(gòu)篇)能力的強(qiáng)弱,這是基礎(chǔ)。
            3、運(yùn)用語言的能力的強(qiáng)弱,這是前提。
            根據(jù)口語表達(dá)循序漸進(jìn)的一般規(guī)律,口語訓(xùn)練的重點(diǎn)應(yīng)是培養(yǎng)敏銳的思維和強(qiáng)烈的語感。具體包括:
            1、語音。學(xué)會科學(xué)發(fā)聲方法,能用準(zhǔn)確、響亮、流暢的英語進(jìn)行口頭表達(dá)。
            2、語調(diào)。能借助聲音高低升降、抑揚(yáng)頓挫的變化來表達(dá)復(fù)雜的感情,掌握停連和輕重、抑揚(yáng)和明暗、快慢和松緊等一般的朗讀技巧。
            3、詞匯。能掌握比較豐富的口語詞匯。
            4、語脈。說話能做到有條有理、語言流暢、上下貫通、一脈相承。
            5、語境。說話注意目的、對象、場合,合乎規(guī)定情景的要求,講禮貌、有針對性。懂得口語修辭。在會話中有隨機(jī)應(yīng)變的能力。
            此外,還要懂得口頭言語的輔助手段--表情、姿勢、動作等態(tài)勢言語的運(yùn)用。
            由于書面語和口語是相互滲透、相互促進(jìn)的,為提高口語的表現(xiàn)力,可在說話訓(xùn)練之前先進(jìn)行一章朗讀、朗誦訓(xùn)練。聽和說是一個(gè)事物的兩個(gè)方面,吸收、表達(dá) 兩者不能偏廢,所以口語訓(xùn)練體系中也應(yīng)包括。通過以上訓(xùn)練,掌握一定的朗讀朗誦技巧,培養(yǎng)準(zhǔn)確、流利、有感情地朗讀朗誦一般作品的能力,特別注意培養(yǎng)強(qiáng)烈 的語感。
            3、聽力訓(xùn)練
            培養(yǎng)聽的注意力、理解力、記憶力和辨析力,提高聽知能力,養(yǎng)成良好的聽的習(xí)慣。
            4、口語表達(dá)基本方式訓(xùn)練
            進(jìn)行敘述、描述、評述、解說等口語表達(dá)基本方式的訓(xùn)練,培養(yǎng)內(nèi)部言語向外部言語迅速轉(zhuǎn)化的能力,結(jié)合進(jìn)行語調(diào)、語脈的訓(xùn)練。
            5、會話型言語訓(xùn)練
            言語形式有會話型和獨(dú)白型兩類。會話是指兩個(gè)以上的人圍繞一個(gè)或幾個(gè)話題一起說話的形式,如交談、座談、辯論、審訊等。會話時(shí)參加者是互為聽、講者 的,因此后面的發(fā)言常常受到前面發(fā)言的制約。另外,由于當(dāng)面交談,大量態(tài)勢語代替了言語表達(dá),會話者的言語結(jié)構(gòu)往往不嚴(yán)謹(jǐn)、不完善,省略句較多。
            可進(jìn)行如下訓(xùn)練:通過交談和辯論兩種會話言語訓(xùn)練,了解它們的一般特點(diǎn)、注意事項(xiàng),結(jié)合進(jìn)行應(yīng)變能力和禮貌用語的訓(xùn)練,從而在會話中有效地培養(yǎng)隨機(jī)應(yīng)變的能力。
            6、獨(dú)白型言語訓(xùn)練
            獨(dú)白是指一個(gè)人單獨(dú)發(fā)言而其他人都作為聽眾的言語表達(dá)形式,如:講故事、作報(bào)告、講課、演講、講解員的解說等。獨(dú)白言語一般不在進(jìn)行過程中跟聽眾問答 交流,因此要求在事先要周密地了解聽眾的要求并系統(tǒng)地組織好發(fā)言內(nèi)容和有關(guān)態(tài)勢語。獨(dú)白是一種高層次的言語形式。
            可通過講故事和演講兩種獨(dú)白言語的訓(xùn)練,了解它們的一般特點(diǎn)、注意事項(xiàng),結(jié)合進(jìn)行運(yùn)用態(tài)勢語的訓(xùn)練,這類訓(xùn)練很有利于培養(yǎng)思維的條理性和連貫性。
            7、即興小品訓(xùn)練
            即興小品要求表演者按照規(guī)定的題目和要求,在規(guī)定的時(shí)間內(nèi),充分發(fā)揮自己的想象,不用或少用道具,通過言語和動作的表演,展現(xiàn)社會生活中的某個(gè)瞬間或片斷,表達(dá)一個(gè)簡單的主題。
            嚴(yán)格地說,小品應(yīng)該是話劇藝術(shù)表演訓(xùn)練的一種形式,但由于它具有綜合的特點(diǎn),對訓(xùn)練思維的創(chuàng)造性、敏捷性、條理性、言語表達(dá)的準(zhǔn)確性、形象性、流暢 性,以及應(yīng)變力,乃至姿勢的綜合運(yùn)用等等,都有很大的好處,所以我們要想英語口語表達(dá)能力更上一個(gè)層次,這種形式的訓(xùn)練也要加以采用。
            懂得了英語口語表達(dá)的規(guī)律,并不等于就有了一口流暢的英語表達(dá)口才,就好象讀了介紹游泳的書并不等于一定會游泳一樣,關(guān)鍵還是要在長期的時(shí)實(shí)踐中持之 以恒地艱苦磨練。這種訓(xùn)練不同于我們平時(shí)常聽常說的那種日常英語口語訓(xùn)練。日常的英語口語訓(xùn)練與之相比簡單得多,所用的詞匯量及話題所涉及的深度都是相當(dāng) 有限的。而真正高層次的英語口語交際所需達(dá)到的流暢性、條理性、敏銳性和靈活性并不是常練一些日常用語就能達(dá)到的,其中用到的詞匯量也因話題的深入和多樣 而大大增加了。
            所以,要想真正地提高英語口語,說一口流利而又有水平的交際英語,得有對英語口語表達(dá)感興趣作為前提,懂得以上的規(guī)律,重視運(yùn)用以上的訓(xùn)練步驟,加上 長期的艱苦訓(xùn)練,才會有成效,才會達(dá)到目的。聽力訓(xùn)練,當(dāng)然,在訓(xùn)練過程中,聽和說是無法截然分開的。
            因此,英語口語訓(xùn)練體系可按以下順序安排:
            1、語音訓(xùn)練
            在學(xué)習(xí)英語語音知識的基礎(chǔ)上加強(qiáng)語音訓(xùn)練,進(jìn)行方音辨正練習(xí)。通過學(xué)習(xí),打好英語語音知識,有一定的辨音能力,能用英語正確、清楚、響亮地表達(dá)。
            2、朗讀朗誦訓(xùn)練
            進(jìn)行呼吸、發(fā)聲與共鳴訓(xùn)練,吐字納音的訓(xùn)練,以及各種朗讀朗誦技巧的訓(xùn)練,學(xué)會常用文體的朗讀、朗誦,懂得在朗誦中恰當(dāng)使用態(tài)勢語


          文章來源:http://blog.163.com/ccbobo_cat/blog/static/3209946220095109201252
          posted @ 2009-06-10 09:20 C.B.K 閱讀(95) | 評論 (0)編輯 收藏

          [關(guān)鍵字]:java,design pattern,設(shè)計(jì)模式,《Java與模式》,Chain of Responsibility,責(zé)任鏈模式
          [環(huán)境]:StarUML5.0 + JDK6
          [作者]:Winty (wintys@gmail.com)
          [正文]:

          package pattern.chainofresponsibility;

          /**
           * 責(zé)任鏈模式:Chain of Responsibility
           * @version 2009-5-9
           * @author Winty(wintys@gmail.com)
           */
          public class ChainOfResponsibilityTest{
              public static void main(String[] args){
                  Handler handler1 = new ConcreteHandler1();
                  Handler handler2 = new ConcreteHandler2();
                  Handler handler3 = new ConcreteHandler3();

                  //設(shè)置責(zé)任鏈
                  handler3.setSuccessor(handler2);
                  handler2.setSuccessor(handler1);

                  //發(fā)送命令
                  handler3.handleRequest();
              }
          }

          /**
           *抽象處理者
           */
          abstract class Handler{
              protected Handler successor;

              public Handler getSuccessor(){
                  return successor;
              }

              public void setSuccessor(Handler successor){
                  this.successor = successor;
              }

              public abstract void handleRequest();
          }

          /**
           *具體處理者
           */
          class ConcreteHandler1 extends Handler{
              public void handleRequest(){
                  if(getSuccessor() != null){
                      System.out.print("Request passed:from class Concrete1");
                      System.out.println(" to class" + getSuccessor().getClass().getName());

                      getSuccessor().handleRequest();
                  }
                  else{
                      System.out.println("Request handled in ConcreteHandler1");
                  }
              }
          }

          /**
           *具體處理者
           */
          class ConcreteHandler2  extends Handler{
              public void handleRequest(){
                  if(getSuccessor() != null){
                      System.out.print("Request passed:from class Concrete2");
                      System.out.println(" to class " + getSuccessor().getClass().getName());

                      getSuccessor().handleRequest();
                  }
                  else{
                      System.out.println("Request handled in ConcreteHandler2");
                  }
              }
          }

          /**
           *具體處理者
           */
          class ConcreteHandler3  extends Handler{
              public void handleRequest(){
                  if(getSuccessor() != null){
                      System.out.print("Request passed:from class Concrete3");
                      System.out.println(" to class " + getSuccessor().getClass().getName());

                      getSuccessor().handleRequest();
                  }
                  else{
                      System.out.println("Request handled in ConcreteHandler3");
                  }
              }
          }

          文章來源:http://blog.163.com/ccbobo_cat/blog/static/320994622009410264843
          posted @ 2009-05-10 14:07 C.B.K 閱讀(89) | 評論 (0)編輯 收藏
          這么一個(gè)需求:同一臺服務(wù)器上有兩個(gè)應(yīng)用,如
          http://hostA:8080/serviceshttp://hostA:8080/admin
          外部訪問時(shí),需要從不同的域名訪問,如
          http://services.host.comhttp://admin.host.com
          一開始給他們這么一個(gè)比較簡單的解決方案:
          分別把services和admin兩個(gè)應(yīng)用,部署到不同的兩個(gè)端口上,如
          services -> http://hostA:8081/
          admin -> http://hostA:8082/
          接著在防火墻配兩個(gè)公網(wǎng)IP,然后dns上把services.host.com和admin.host.com配置到這兩個(gè)IP上。
          當(dāng)請求到達(dá)防火墻時(shí),防火墻根據(jù)所訪問的ip轉(zhuǎn)發(fā)到hostA的對應(yīng)端口上。
          前 方用的防火墻是我們公司的Audemon 100,和公司的Audemon系統(tǒng)組的交流后得知,目前的防火墻版本不支持同時(shí)配置兩個(gè)ip,要到六月底才能出版本支持。!@…%#%…%¥,暈倒,好 像這是很基本的功能來的吧,居然還不支持。沒辦法,此路不通。由于防火墻是不管域名的(因?yàn)橛蛎Y料是通過應(yīng)用層傳輸?shù)?,那更別指望防火墻根據(jù)域名轉(zhuǎn)發(fā) 了。
          因此,我們只好提供了軟件級的解決方案,讓前方在Tomcat前加一個(gè)Apache 2.2,通過Apache的Virtual Host + AJP實(shí)現(xiàn)轉(zhuǎn)發(fā)。
          Apache的部分配置如下:
          NameVirtualHost *:80
          <VirtualHost *:80>
          ServerName host1.com
          ProxyPass / ajp://host1.com:8009/
          ProxyPassReverse / ajp://host1.com:8009/
          </VirtualHost>
          <VirtualHost *:80>
          ServerName host2.com
          ProxyPass / ajp://host2.com:8019/
          ProxyPassReverse / ajp://host2.com:8019/
          </VirtualHost>
          Tomcat也需要配置AJP Connector,如host1.com的配置
          <Connector port=”8009″ enableLookups=”false” redirectPort=”8443″ protocol=”AJP/1.3″ />
          這個(gè)方案相對于防火墻的硬件方案,性能上要差一些,但還是不錯(cuò)的。
          另 外還有一種方案是通過iptables的domain module來實(shí)現(xiàn),但這個(gè)domain module好像是國內(nèi)的某個(gè)高手寫的,只更新到v0.02版本,并沒有提交到iptables的標(biāo)準(zhǔn)里。雖然可以用而且性能比Apache的方案要高一 些,但是風(fēng)險(xiǎn)較大,而且配置麻煩(既要編譯內(nèi)核,又要配置iptables的rules),所以沒有用這種方式。

          文章來源:http://blog.163.com/ccbobo_cat/blog/static/320994622009326115641438
          posted @ 2009-04-26 11:57 C.B.K 閱讀(4205) | 評論 (0)編輯 收藏
          隨著訪問量的不斷提高,以及對響應(yīng)速度的要求,進(jìn)行負(fù)載均衡設(shè)置就顯得非常必要了。公司的系統(tǒng)在最初設(shè)計(jì)的時(shí)候就已經(jīng)考慮到了負(fù)載均衡的規(guī)劃,www靜態(tài) 服務(wù)器配置了兩臺,由于初期項(xiàng)目時(shí)間緊,并且訪問量并不高,所以當(dāng)時(shí)只用了一臺,另一臺在內(nèi)網(wǎng)中,只是進(jìn)行了同步,并為發(fā)揮出效用來。此次就是對負(fù)載均衡 的一個(gè)簡單測試。
                 先介紹一下apache mod_proxy_balancer的幾個(gè)配置規(guī)則(從網(wǎng)上找的):
          將Apache作為LoadBalance前置機(jī)分別有三種不同的部署方式,分別是:

          1 )輪詢均衡策略的配置

          進(jìn)入Apache的conf目錄,打開httpd.conf文件,在文件的末尾加入:
          ProxyPass / balancer://proxy/         #注意這里以"/"結(jié)尾
          <Proxy balancer://proxy> 
                 BalancerMember http://192.168.6.37:6888/ 
                 BalancerMember http://192.168.6.38:6888/
          </Proxy> 
                我們來觀察上述的參數(shù)“ProxyPass / balancer://proxy/”,其中,“ProxyPass”是配置虛擬服務(wù)器的命令,“/”代表發(fā)送Web請求的URL前綴,如:http://myserver/或者h(yuǎn)ttp://myserver/aaa,這些URL都將符合上述過濾條件;“balancer://proxy/”表示要配置負(fù)載均衡,proxy代表負(fù)載均衡名;BalancerMember 及其后面的URL表示要配置的后臺服務(wù)器,其中URL為后臺服務(wù)器請求時(shí)的URL。以上面的配置為例,實(shí)現(xiàn)負(fù)載均衡的原理如下: 
                假設(shè)Apache接收到http://localhost/aaa請求,由于該請求滿足ProxyPass條件(其URL前綴為“/”),該請求會被分發(fā)到后臺某一個(gè)BalancerMember,譬如,該請求可能會轉(zhuǎn)發(fā)到 http://192.168.6.37:6888/aaa進(jìn)行處理。當(dāng)?shù)诙€(gè)滿足條件的URL請求過來時(shí),該請求可能會被分發(fā)到另外一臺BalancerMember,譬如,可能會轉(zhuǎn)發(fā)到http://192.168.6.38:6888/。如此循環(huán)反復(fù),便實(shí)現(xiàn)了負(fù)載均衡的機(jī)制。

          2) 按權(quán)重分配均衡策略的配置

          ProxyPass / balancer://proxy/         #注意這里以"/"結(jié)尾

          <Proxy balancer://proxy> 
                  BalancerMember http://192.168.6.37:6888/  loadfactor=3 
                  BalancerMember http://192.168.6.38:6888/  loadfactor=1
          </Proxy> 
                參數(shù)”loadfactor”表示后臺服務(wù)器負(fù)載到由Apache發(fā)送請求的權(quán)值,該值默認(rèn)為1,可以將該值設(shè)置為1到100之間的任何值。以上面的配置 為例,介紹如何實(shí)現(xiàn)按權(quán)重分配的負(fù)載均衡,現(xiàn)假設(shè)Apache收到http://myserver/aaa 4次這樣的請求,該請求分別被負(fù)載到后臺服務(wù)器,則有3次連續(xù)的這樣請求被負(fù)載到BalancerMember為http://192.168.6.37:6888的服務(wù)器,有1次這樣的請求被負(fù)載BalancerMember為http://192.168.6.38:6888后臺服務(wù)器。實(shí)現(xiàn)了按照權(quán)重連續(xù)分配的均衡策略。

          3) 權(quán)重請求響應(yīng)負(fù)載均衡策略的配置

          ProxyPass / balancer://proxy/ lbmethod=bytraffic  #注意這里以"/"結(jié)尾

          <Proxy balancer://proxy> 
                   BalancerMember http://192.168.6.37:6888/  loadfactor=3 
                   BalancerMember http://192.168.6.38:6888/  loadfactor=1 
           </Proxy> 
                 參數(shù)“l(fā)bmethod=bytraffic”表示后臺服務(wù)器負(fù)載請求和響應(yīng)的字節(jié)數(shù),處理字節(jié)數(shù)的多少是以權(quán)值的方式來表示的。 “l(fā)oadfactor”表示后臺服務(wù)器處理負(fù)載請求和響應(yīng)字節(jié)數(shù)的權(quán)值,該值默認(rèn)為1,可以將該值設(shè)置在1到100的任何值。根據(jù)以上配置是這么進(jìn)行均 衡負(fù)載的,假設(shè)Apache接收到http://myserver/aaa請求,將請求轉(zhuǎn)發(fā)給后臺服務(wù)器,如果BalancerMember為http://192.168.6.37:6888后臺服務(wù)器負(fù)載到這個(gè)請求,那么它處理請求和響應(yīng)的字節(jié)數(shù)是BalancerMember為http://192.168.6.38:6888 服務(wù)器的3倍(回想(2)均衡配置,(2)是以請求數(shù)作為權(quán)重負(fù)載均衡的,(3)是以流量為權(quán)重負(fù)載均衡的,這是最大的區(qū)別)。

          看明白了沒有,根據(jù)不同的需要,可以按這三種方式進(jìn)行配置。我按照第三種配置的,感覺上這種對于負(fù)載的均衡更全面合理。我的配置很簡單,如下:
          先配置均衡器:
          <Proxy balancer://proxy>
                 BalancerMember ajp://127.0.0.1:8009/  loadfactor=1
                 BalancerMember http://192.168.10.6:8083/  loadfactor=1
          </Proxy>
          其中http://192.168.10.6:8083實(shí)際上是另外一個(gè)端口啟動的apache,為了測試,它就簡單的直接轉(zhuǎn)發(fā)所有請求到tomcat。
          對于上次的VirtualHost進(jìn)行以下的修改即可:
          <VirtualHost *:80>
                  ServerName www.test.com
                  DocumentRoot /www
                  DirectoryIndex index.html index.jsp
                  <Directory "/www">
                      Options Indexes FollowSymLinks
                      AllowOverride None
                      Order allow,deny
                      Allow from all
                  </Directory>
                  <Directory "/control">
                      Options Indexes FollowSymLinks
                      AllowOverride None
                      Order allow,deny
                      Allow from all
                  </Directory>
                  ProxyPass /nxt/images/ !
                  ProxyPass /nxt/js/ !
                  ProxyPass /nxt/css/ !
                  #ProxyPass / ajp://127.0.0.1:8009/
                  #ProxyPassReverse / ajp://127.0.0.1:8009/
                  ProxyPass / balancer://proxy/
                  ProxyPassReverse / balancer://proxy/
          </VirtualHost>
          注釋掉之前的ajp轉(zhuǎn)發(fā),而配置成通過balancer去處理。
          通過觀察access log,的確有部分請求發(fā)送到了8083端口的apache上,而有部分是直接ajp轉(zhuǎn)發(fā)到tomcat上了。對于更多的負(fù)載均衡的參數(shù)檢測,待空了再做。


          文章來源:http://blog.163.com/ccbobo_cat/blog/static/32099462200932611555639
          posted @ 2009-04-26 11:56 C.B.K 閱讀(151) | 評論 (0)編輯 收藏

          一、集群和負(fù)載均衡的概念

          (一)集群的概念

            集群(Cluster)是由兩臺或多臺節(jié)點(diǎn)機(jī)(服務(wù)器)構(gòu)成的一種松散耦合的計(jì)算節(jié)點(diǎn)集合,為用 戶提供網(wǎng)絡(luò)服務(wù)或應(yīng)用程序(包括數(shù)據(jù)庫、Web服務(wù)和文件服務(wù)等)的單一客戶視圖,同時(shí)提供接近容錯(cuò)機(jī)的故障恢復(fù)能力。集群系統(tǒng)一般通過兩臺或多臺節(jié)點(diǎn)服 務(wù)器系統(tǒng)通過相應(yīng)的硬件及軟件互連,每個(gè)群集節(jié)點(diǎn)都是運(yùn)行其自己進(jìn)程的獨(dú)立服務(wù)器。這些進(jìn)程可以彼此通信,對網(wǎng)絡(luò)客戶機(jī)來說就像是形成了一個(gè)單一系統(tǒng),協(xié) 同起來向用戶提供應(yīng)用程序、系統(tǒng)資源和數(shù)據(jù)。除了作為單一系統(tǒng)提供服務(wù),集群系統(tǒng)還具有恢復(fù)服務(wù)器級故障的能力。集群系統(tǒng)還可通過在集群中繼續(xù)增加服務(wù)器 的方式,從內(nèi)部增加服務(wù)器的處理能力,并通過系統(tǒng)級的冗余提供固有的可靠性和可用性。
          (二)集群的分類
          1、高性能計(jì)算科學(xué)集群:
             以解決復(fù)雜的科學(xué)計(jì)算問題為目的的IA集群系統(tǒng)。是并行計(jì)算的基礎(chǔ),它可以不使用專門的由十至上萬個(gè)獨(dú)立處理器組成的并行超級計(jì)算機(jī),而是采用通過高速 連接來鏈接的一組1/2/4 CPU的IA服務(wù)器,并且在公共消息傳遞層上進(jìn)行通信以運(yùn)行并行應(yīng)用程序。這樣的計(jì)算集群,其處理能力與真正超級并行機(jī)相等,并且具有優(yōu)良的性價(jià)比。
          2、負(fù)載均衡集群:
             負(fù)載均衡集群為企業(yè)需求提供更實(shí)用的系統(tǒng)。該系統(tǒng)使各節(jié)點(diǎn)的負(fù)載流量可以在服務(wù)器集群中盡可能平均合理地分?jǐn)偺幚怼T撠?fù)載需要均衡計(jì)算的應(yīng)用程序處理端 口負(fù)載或網(wǎng)絡(luò)流量負(fù)載。這樣的系統(tǒng)非常適合于運(yùn)行同一組應(yīng)用程序的大量用戶。每個(gè)節(jié)點(diǎn)都可以處理一部分負(fù)載,并且可以在節(jié)點(diǎn)之間動態(tài)分配負(fù)載,以實(shí)現(xiàn)平 衡。對于網(wǎng)絡(luò)流量也如此。通常,網(wǎng)絡(luò)服務(wù)器應(yīng)用程序接受了大量入網(wǎng)流量,無法迅速處理,這就需要將流量發(fā)送給在其它節(jié)點(diǎn)。負(fù)載均衡算法還可以根據(jù)每個(gè)節(jié)點(diǎn) 不同的可用資源或網(wǎng)絡(luò)的特殊環(huán)境來進(jìn)行優(yōu)化。
          3、高可用性集群:
            為保證集群整體服務(wù)的高可用,考慮計(jì)算硬件和軟件的容錯(cuò)性。如果高可用性群集中的某個(gè)節(jié)點(diǎn)發(fā)生了故障,那么將由另外的節(jié)點(diǎn)代替它。整個(gè)系統(tǒng)環(huán)境對于用戶是一致的。

            實(shí)際應(yīng)用的集群系統(tǒng)中,這三種基本類型經(jīng)常會發(fā)生混合與交雜。

          (三)典型集群
          科學(xué)計(jì)算集群:
          1、Beowulf
          當(dāng)談到 Linux 集群時(shí),許多人的第一反映是 Beowulf。那是最著名的 Linux科學(xué)軟件集群系統(tǒng)。實(shí)際上,它是一組適用于在 Linux 內(nèi)核上運(yùn)行的公共軟件包的通稱。其中包括流行的軟件消息傳遞 API,如“消息傳送接口”(MPI) 或“并行虛擬機(jī)”(PVM),對 Linux 內(nèi)核的修改,以允許結(jié)合幾個(gè)以太網(wǎng)接口、高性能網(wǎng)絡(luò)驅(qū)動器,對虛擬內(nèi)存管理器的更改,以及分布式進(jìn)程間通信 (DIPC) 服務(wù)。公共全局進(jìn)程標(biāo)識空間允許使用 DIPC 機(jī)制從任何節(jié)點(diǎn)訪問任何進(jìn)程。
          2、MOSIX
          Beowulf類似于給系統(tǒng)安裝的一個(gè)支持 集群的外掛軟件,提供了應(yīng)用級的集群能力。而MOSIX是徹底修改Linux的內(nèi)核,從系統(tǒng)級提供了集群能力,它對應(yīng)用而言是完全透明的,原有的應(yīng)用程 序,可以不經(jīng)改動,就能正常運(yùn)行在MOSIX系統(tǒng)之上。集群中的任何節(jié)點(diǎn)都可以自由地加入和移除,來接替其它節(jié)點(diǎn)的工作,或是擴(kuò)充系統(tǒng)。MOSIX 使用自適應(yīng)進(jìn)程負(fù)載均衡和內(nèi)存引導(dǎo)算法使整體性能最大化。應(yīng)用程序進(jìn)程可以在節(jié)點(diǎn)之間實(shí)現(xiàn)遷移,以利用最好的資源,這類似于對稱多處理器系統(tǒng)可以在各個(gè)處 理器之間切換應(yīng)用程序。由于MOSIX通過修改內(nèi)核來實(shí)現(xiàn)集群功能,所以存在兼容性問題,部分系統(tǒng)級應(yīng)用程序?qū)o法正常運(yùn)行。

          負(fù)載均衡/高可用性集群
          3、LVS(Linux Virtual Server)
          這是一個(gè)由國人主持的項(xiàng)目。
          它是一個(gè)負(fù)載均衡/高可用性集群,主要針對大業(yè)務(wù)量的網(wǎng)絡(luò)應(yīng)用(如新聞服務(wù)、網(wǎng)上銀行、電子商務(wù)等)。
          LVS 是建立在一個(gè)主控服務(wù)器(通常為雙機(jī))(director)及若干真實(shí)服務(wù)器(real-server)所組成的集群之上。real-server負(fù)責(zé)實(shí) 際提供服務(wù),主控服務(wù)器根據(jù)指定的調(diào)度算法對real-server進(jìn)行控制。而集群的結(jié)構(gòu)對于用戶來說是透明的,客戶端只與單個(gè)的IP(集群系統(tǒng)的虛擬 IP)進(jìn)行通信,也就是說從客戶端的視角來看,這里只存在單個(gè)服務(wù)器。
          N54537Real-server可以提供眾多服務(wù),如ftp, http, dns, telnet, nntp, smtp 等。主控服務(wù)器負(fù)責(zé)對Real-Server進(jìn)行控制。客戶端在向LVS發(fā)出服務(wù)請求時(shí),Director會通過特定的調(diào)度算法來指定由某個(gè)Real- Server來應(yīng)答請求,而客戶端只與Load Balancer的IP(即虛擬IP,VIP)進(jìn)行通信。

          其他集群:
          現(xiàn)在集群系統(tǒng)可謂五花八門,絕大部分的OS開發(fā)商,服務(wù)器開發(fā)商都提供了系統(tǒng)級的 集群產(chǎn)品,最典型的是各類雙機(jī)系統(tǒng),還有各類科研院校提供的集群系統(tǒng)。以及各類軟件開發(fā)商提供的應(yīng)用級別的集群系統(tǒng),如數(shù)據(jù)庫集 群,Application Server 集群,Web Server集群,郵件集群等等。

          (四)負(fù)載均衡

          1、概念

              由于目前現(xiàn)有網(wǎng)絡(luò)的各個(gè)核心部分隨著業(yè)務(wù)量的提高,訪問量和數(shù)據(jù)流量的快速增長,其處理能力和計(jì)算強(qiáng)度也相應(yīng)地增大,使得單一的服務(wù)器設(shè)備根本無法承擔(dān)。 在此情況下,如果扔掉現(xiàn)有設(shè)備去做大量的硬件升級,這樣將造成現(xiàn)有資源的浪費(fèi),而且如果再面臨下一次業(yè)務(wù)量的提升時(shí),這又將導(dǎo)致再一次硬件升級的高額成本 投入,甚至性能再卓越的設(shè)備也不能滿足當(dāng)前業(yè)務(wù)量增長的需求。

          針對此情況而衍生出來的一種廉價(jià)有效透明的方法以擴(kuò)展現(xiàn)有網(wǎng)絡(luò)設(shè)備和服務(wù)器的帶寬、增加吞吐量、加強(qiáng)網(wǎng)絡(luò)數(shù)據(jù)處理能力、提高網(wǎng)絡(luò)的靈活性和可用性的技術(shù)就是負(fù)載均衡(Load Balance)。

          2、特點(diǎn)和分類

               負(fù)載均衡(Server Load Balance)一般用于提高服務(wù)器的整體處理能力,并提高可靠性,可用性,可維護(hù)性,最終目的是加快服務(wù)器的響應(yīng)速度,從而提高用戶的體驗(yàn)度。  

               負(fù)載均衡從結(jié)構(gòu)上分為本地負(fù)載均衡(Local Server Load Balance)和地域負(fù)載均衡(Global Server Load Balance)(全局負(fù)載均衡),一是指對本地的服務(wù)器群做負(fù)載均衡,另一是指對分別放置在不同的地理位置、有不同的網(wǎng)絡(luò)及服務(wù)器群之間作負(fù)載均衡。   

          地域負(fù)載均衡有以下的特點(diǎn):

          (1)解決網(wǎng)絡(luò)擁塞問題,服務(wù)就近提供,實(shí)現(xiàn)地理位置無關(guān)性

          (2)對用戶提供更好的訪問質(zhì)量

          (3)提高服務(wù)器響應(yīng)速度

          (4)提高服務(wù)器及其他資源的利用效率

          (5)避免了數(shù)據(jù)中心單點(diǎn)失效

          3、負(fù)載均衡技術(shù)主要應(yīng)用

          (1)DNS負(fù)載均衡 最早的負(fù)載均衡技術(shù)是通過DNS來實(shí)現(xiàn)的,在DNS中為多個(gè)地址配置同一個(gè)名字,因而查詢這個(gè)名字的客戶機(jī)將得到其中一個(gè)地址,從而使得不同的客戶訪問不 同的服務(wù)器,達(dá)到負(fù)載均衡的目的。DNS負(fù)載均衡是一種簡單而有效的方法,但是它不能區(qū)分服務(wù)器的差異,也不能反映服務(wù)器的當(dāng)前運(yùn)行狀態(tài)。

          (2)代理服務(wù)器負(fù)載均衡 使用代理服務(wù)器,可以將請求轉(zhuǎn)發(fā)給內(nèi)部的服務(wù)器,使用這種加速模式顯然可以提升靜態(tài)網(wǎng)頁的訪問速度。然而,也可以考慮這樣一種技術(shù),使用代理服務(wù)器將請求均勻轉(zhuǎn)發(fā)給多臺服務(wù)器,從而達(dá)到負(fù)載均衡的目的。

          (3)地址轉(zhuǎn)換網(wǎng)關(guān)負(fù)載均衡 支持負(fù)載均衡的地址轉(zhuǎn)換網(wǎng)關(guān),可以將一個(gè)外部IP地址映射為多個(gè)內(nèi)部IP地址,對每次TCP連接請求動態(tài)使用其中一個(gè)內(nèi)部地址,達(dá)到負(fù)載均衡的目的。

          (4)協(xié)議內(nèi)部支持負(fù)載均衡 除了這三種負(fù)載均衡方式之外,有的協(xié)議內(nèi)部支持與負(fù)載均衡相關(guān)的功能,例如HTTP協(xié)議中的重定向能力等,HTTP運(yùn)行于TCP連接的最高層。

          (5)NAT 負(fù)載均衡 NAT(Network Address Translation 網(wǎng)絡(luò)地址轉(zhuǎn)換)簡單地說就是將一個(gè)IP地址轉(zhuǎn)換為另一個(gè)IP地址,一般用于未經(jīng)注冊的內(nèi)部地址與合法的、已獲注冊的Internet IP地址間進(jìn)行轉(zhuǎn)換。適用于解決Internet IP地址緊張、不想讓網(wǎng)絡(luò)外部知道內(nèi)部網(wǎng)絡(luò)結(jié)構(gòu)等的場合下。

          (6)反向代理負(fù)載均 衡 普通代理方式是代理內(nèi)部網(wǎng)絡(luò)用戶訪問internet上服務(wù)器的連接請求,客戶端必須指定代理服務(wù)器,并將本來要直接發(fā)送到internet上服務(wù)器的連 接請求發(fā)送給代理服務(wù)器處理。反向代理(Reverse Proxy)方式是指以代理服務(wù)器來接受internet上的連接請求,然后將請求轉(zhuǎn)發(fā)給內(nèi)部網(wǎng)絡(luò)上的服務(wù)器,并將從服務(wù)器上得到的結(jié)果返回給 internet上請求連接的客戶端,此時(shí)代理服務(wù)器對外就表現(xiàn)為一個(gè)服務(wù)器。反向代理負(fù)載均衡技術(shù)是把將來自internet上的連接請求以反向代理的 方式動態(tài)地轉(zhuǎn)發(fā)給內(nèi)部網(wǎng)絡(luò)上的多臺服務(wù)器進(jìn)行處理,從而達(dá)到負(fù)載均衡的目的。

          (7)混合型負(fù)載均衡 在有些大型網(wǎng)絡(luò),由于多個(gè)服務(wù)器群內(nèi)硬件設(shè)備、各自的規(guī)模、提供的服務(wù)等的差異,我們可以考慮給每個(gè)服務(wù)器群采用最合適的負(fù)載均衡方式,然后又在這多個(gè)服 務(wù)器群間再一次負(fù)載均衡或群集起來以一個(gè)整體向外界提供服務(wù)(即把這多個(gè)服務(wù)器群當(dāng)做一個(gè)新的服務(wù)器群),從而達(dá)到最佳的性能。我們將這種方式稱之為混合 型負(fù)載均衡。此種方式有時(shí)也用于單臺均衡設(shè)備的性能不能滿足大量連接請求的情況下。

          二、搭建集群和實(shí)現(xiàn)負(fù)載平衡

          (一)前期準(zhǔn)備

          我的系統(tǒng)用的是windowsXP專業(yè)版,我要做的是,用一個(gè)apache和多個(gè)(這里以兩個(gè)作為示例)tomcat,通過jk方式,構(gòu)造一個(gè)集群。以下是要首先準(zhǔn)備的東西:

          1、jdk,我用的版本是jdk1.5.0_06,下載地址是http://192.18.108.216/ECom/EComTicketServlet/BEGIND597A309654D73D910E051D73D539D5F/-2147483648/2438196255/1/852050/851882/2438196255/2ts+/westCoastFSEND/jdk-1.5.0_13-oth-JPR/jdk-1.5.0_13-oth-JPR:3/jdk-1_5_0_13-windows-i586-p.exe

          2、apache,我用的版本是2.2.4,下載地址是http://apache.justdn.org/httpd/binaries/win32/apache_2.2.4-win32-x86-openssl-0.9.8d.msi

          3、tomcat,我用的版本是5.5的解壓版本,這里要注意:不能用安裝的版本,因?yàn)橐慌_機(jī)器上裝兩個(gè)一樣的tomcat,是會出錯(cuò)誤的。下載地址是http://apache.mirror.phpchina.com/tomcat/tomcat-5/v5.5.25/bin/apache-tomcat-5.5.25.zip

          4、jk,這個(gè)jk的版本,本來有兩個(gè)的,但是版本2已經(jīng)被廢棄掉了,目前可用的jk版本是1.2.25。每個(gè)apache的版本,都會有一個(gè)特定的jk與之對應(yīng),所以這里要用的jk也必須是為apache-2.2.4開發(fā)的那個(gè)才行。它的下載地址是http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/win32/jk-1.2.25/mod_jk-apache-2.2.4.so

          有了這四樣?xùn)|西,我們就可以開始做集群了。

          (二)安裝

          1、相信需要看這篇文章的人,JDK的安裝一定不會陌生,這里不在贅述。只是需要提醒一下:環(huán)境變量別忘記配置了。

          2、安裝apache也沒有什么難度,就是在安裝過程中要配置域名、網(wǎng)址和管理員郵箱之類的信息,這 個(gè)信息完全可以按照提示,然后修改下填入即可,之后想修改的話直接到配置文件中改就行了。除了這個(gè)地方,還要保證機(jī)器上的80端口沒有被其他程序占用。至 于安裝路徑,完全取決于個(gè)人愛好。其他的默認(rèn)就行了。安裝成功后,系統(tǒng)右下角的托盤區(qū)會有個(gè)圖標(biāo),我們可以通過這個(gè)啟動apache,如果那個(gè)小紅點(diǎn)變成 綠色,說明服務(wù)已經(jīng)正常啟動了(如果服務(wù)沒有啟動起來,說明安裝過程中的配置有錯(cuò)誤,建議卸載后重裝)。如果按照默認(rèn),端口是80的話,那打開瀏覽器,輸 入:http://localhost/ ,應(yīng)該可以看到 " It works “的字樣。這樣就可以進(jìn)入下一步了。

          3、解壓縮tomcat,記得要做兩份。這里不妨將兩個(gè)tomcat命名為:tomcat- 5.5.25_1和tomcat-5.5.25_2,其實(shí)這兩個(gè)文件夾中的東西是完全一樣的。但是我為了在同一臺機(jī)器上做集群,那就要保證兩個(gè) tomcat運(yùn)行起來不會在端口上起沖突。進(jìn)入tomcat-5.5.25_1/conf目錄,用文本編輯器打開并修改server.xml,將該 tomcat的默認(rèn)8080端口改為8088(其實(shí)沒必要改,我改這個(gè)是因?yàn)槲覚C(jī)器上還有其他tomcat占用著8080端口)。然后進(jìn)入tomcat- 5.5.25_2/conf目錄,同樣將8080修改掉,至于改成多少沒多大關(guān)系,只要不占用其他程序的端口,應(yīng)該不會出什么問題。這樣,tomcat就 算安裝好了。

          4、jk這東西是一個(gè)連接模塊,不用安裝,直接將mod_jk-apache-2.2.4.so這個(gè)文件拷貝到apache安裝目錄下的modules文件夾下面就行了。

          這樣,安裝完成,下面開始配置。

          (三)配置

          這個(gè)地方才是搭建集群的關(guān)鍵所在,我也會盡我的可能寫的詳細(xì)點(diǎn)。

          1、配置tomcat

          為防止沖突,進(jìn)入第二個(gè)tomcat主目錄,然后進(jìn)入conf目錄,打開server.xml修改配 置。主要是修改端口,我這里把所有的端口信息,都在原有基礎(chǔ)上加1000,即原端口是8009,我改為9009。當(dāng)然,你不必和我一樣,只要保證不沖突就 OK!這些配置在apache的配置中可能會用到。

          2、配置apache

          (1)進(jìn)入apache的主目錄,然后進(jìn)入conf文件夾,用文本編輯器打開httpd.conf,在該文件末尾加上如下幾行:

          ### 加載 mod_jk 模塊
          LoadModule jk_module modules/mod_jk-apache-2.2.4.so

          ### 配置 mod_jk
          JkWorkersFile conf/workers.properties           #加載集群中的workers
          JkMountFile conf/uriworkermap.properties    #加載workers的請求處理分配文件
          JkLogFile logs/mod_jk.log                                #指定jk的日志輸出文件
          JkLogLevel warn                                                  #指定日志級別

          (2)不要改變目錄,新建一個(gè)文件:workers.properties,該文件用來配置web容器的信息。該文件的內(nèi)容如下:

          # worker列表
          worker.list=controller, status

          #第一個(gè)server的配置,server名為s1
          #ajp13 端口號,在tomcat下server.xml配置,默認(rèn)8009
          worker.s1.port=8009
          #tomcat的主機(jī)地址,如不為本機(jī),請?zhí)顚慽p地址
          worker.s1.host=localhost
          worker.s1.type=ajp13
          #server的加權(quán)比重,值越高,分得的請求越多
          worker.s1.lbfactor=1

          #第二個(gè)server的配置,server名為s2
          worker.s2.port=9009
          worker.s2.host=localhost
          worker.s2.type=ajp13
          worker.s2.lbfactor=1

          #server名為controller,用于負(fù)載均衡
          worker.controller.type=lb
          worker.retries=3   #重試次數(shù)
          #指定分擔(dān)請求的server列表,用逗號分隔
          worker.controller.balanced_workers=s1,s2
          #設(shè)置用于負(fù)載均衡的server的session可否共享 有不少文章說設(shè)置為1是可以的,但是我是設(shè)置為0才可以的
          worker.controller.sticky_session=0
          #worker.controller.sticky_session_force=1

          worker.status.type=status

          (3)不要改變目錄,新建一個(gè)文件:uriworkermap.properties,文件內(nèi)容如下:

          /*=controller                         #所有請求都由controller這個(gè)server處理
          /jkstatus=status                   #所有包含jkstatus請求的都由status這個(gè)server處理

          !/*.gif=controller                   #所有以.gif結(jié)尾的請求都不由controller這個(gè)server處理,以下幾個(gè)都是一樣的意思
          !/*.jpg=controller
          !/*.png=controller
          !/*.css=controller
          !/*.js=controller
          !/*.htm=controller
          !/*.html=controller

          這里的"!”類似于java中的"!”,是“非”的意思。

          這樣,apache一塊就配置好了。

          3、再修改tomcat配置:這里兩個(gè)tomcat都要配置。

          仍然是打開第一步中的那個(gè)server.xml文件,找到<Engine name="Catalina" defaultHost="localhost">這一行,在里面加上一句:jvmRoute="s1",即把該句改為:<Engine name="Catalina" defaultHost="localhost" jvmRoute="s1">。這里的s1就是第二步中配置的用于負(fù)載均衡的server的名稱。如果該tomcat的端口是第二步中s1用的端 口,那這里就寫s1,第二個(gè)tomcat就應(yīng)該是s2了。

          這樣,配置就完成了。

          (四)運(yùn)行

          進(jìn)入兩個(gè)tomcat的bin目錄,執(zhí)行兩個(gè)tomcat的startup.bat啟動這兩個(gè) tomcat,然后將apache重新啟動后,運(yùn)行起來看看效果吧。如果不出意外,兩個(gè)tomcat的窗口應(yīng)該是你一次我一次的打印日志信息了,而且此時(shí) session也是共享了的。

          到這里,集群搭建好了,負(fù)載均衡也實(shí)現(xiàn)了。


          文章來源:http://blog.163.com/ccbobo_cat/blog/static/32099462200932611544216
          posted @ 2009-04-26 11:54 C.B.K 閱讀(197) | 評論 (0)編輯 收藏
          附錄B SQL*PLUS
          Sql*plus 中使用綁定變量:
          sql> variable x number;
          sql> exec :x := 7788;
          sql> SELECT empno,ename from scott.emp where empno=:x;
          SQL*PLUS 是Oracle提供的一個(gè)工具程序,它不僅可以用于測試,運(yùn)行SQL語句和PL/SQL塊,而且還可以用于管理Oracle數(shù)據(jù)庫,
          1.啟動sql*plus
          為了使用sql*plus,必須首先要啟動sql*plus。Oracle不僅提供了命令行和圖形界面的sql*plus,而且還可以在web瀏覽器中
          運(yùn)行.
          (1)在命令運(yùn)行sql*plus
          在命令行運(yùn)行sql*plus是使用sqlplus命令來完成的,該命令適用于任何操作系統(tǒng)平臺,
          語法如下:
             sqlplus [username]/[password][@server]
          如上所示:username用于指定數(shù)據(jù)庫用戶名,password用于指定用戶口令,server則用于指定主機(jī)字符串(網(wǎng)絡(luò)服務(wù)名).
          當(dāng)連接到本地?cái)?shù)據(jù)時(shí),不需要提供網(wǎng)絡(luò)服務(wù)名,如果要連接到遠(yuǎn)程數(shù)據(jù)庫,則必須要使用網(wǎng)絡(luò)服務(wù)名.
          (2)在windows環(huán)境中運(yùn)行sql*plus
          如果在windows環(huán)境中安裝了oralce數(shù)據(jù)庫產(chǎn)品,那么可以在窗口環(huán)境中運(yùn)行sql*plus
          具體方法: "開始->程序->oracle-oradb10g_home1->application development->sql*plus"
          2.連接命令
          (1)conn[ect]
             該命令用于連接到數(shù)據(jù)庫。注意,使用該命令建立新會話時(shí),會自動斷開先前會話,示例如下:
             sql>conn scott/yhai1981@demo
          (2)disc[onnect]
             該命令用于斷開已經(jīng)存在的數(shù)據(jù)庫連接。注:該命令只是斷開連接會話,而不會退出sql*plus,示例如下:
             sql>disc
          (3)passw[ord]
             該命令用于修改用戶的口令。注,任何用戶都可以使用該命令修改其自身口令,但如果要修改其他用戶的口令時(shí),
          則必須以DBA身份(sys和system)登錄,在sql*plus中,當(dāng)修改用戶口令時(shí),可以使用該命令取代sql命令alter user,
             示例如下:
          sql>passw
          更改scott的口令
          舊口令:******
          新口令:******
          重新鍵入新口令:******
          口令已更改
          sql>
          (4)exit
          該命令用于退出 sql*plus,另外你也可以使用quit命令退出sql*plus.使用該命令不僅會斷開連接,而且也會退出sql*plus
          注:默認(rèn)情況下,當(dāng)執(zhí)行該命令時(shí)會自動提交事務(wù)。
          3,編輯命令
          (1)l[ist]
             該命令用于列出sql緩沖區(qū)的內(nèi)容,使用該命令可以列出sql緩沖某行,某幾行或所有行的內(nèi)容。在顯示結(jié)果中,數(shù)據(jù)字為具體
          的行號,而"*"則表示當(dāng)前行。
          示例一:列出sql緩沖區(qū)所有內(nèi)容
               sql>l
          示例二:列出sql緩沖區(qū)首行內(nèi)容:
               sql>l1
          (2)a[ppend]
             該命令用于在sql緩沖區(qū)的當(dāng)前行尾部添加內(nèi)容。注:該命令將內(nèi)容追加到標(biāo)記為"*"的行的尾部,示例如下:
             sql>l
               1 select empno,ename,sal,hiredate,comm,deptno
               2 from emp
               3* where deptno=10
             sql>a and job='CLERK'
             sql>l
             SQL> list
              1 select empno,ename,sal,hiredate,comm,deptno
              2 from emp
              3* where deptno=10 and job='CLERK'
          (3)c[hange]
             該命令用于修改sql緩沖區(qū)的內(nèi)容。如果在編寫sql語句時(shí)寫錯(cuò)了某個(gè)詞,那么使用該命令可以進(jìn)行修改,
              sql>select ename from temp where deptno=10;
              SQL> c /temp/emp
                1* select ename from emp where deptno=10
          (4)del
             該命令用于刪除sql緩沖區(qū)中內(nèi)容,使用它可以刪除某行,某幾行或所有行,在默認(rèn)情況下,當(dāng)直接執(zhí)行
          del時(shí),只刪除當(dāng)前行的內(nèi)容,示例如下:
             SQL> l
             1 select ename
             2 from emp
             3* where deptno=20
             sql>del
             SQL> l
             1 select ename
             2* from emp
             如果一次要刪除多行,則指定起始行號和終止行號,例如"del 3 5"
          (5)i[nput]
             該命令用于在sql緩沖區(qū)的當(dāng)前行后新增加一行。示例如下:
             SQL> l
              1 select ename
              2* from emp
             sql>i where deptno=30
             如果要在首行前增加內(nèi)容,則使用"0文本"
             sql>0 create table temp as
             SQL> l
          1 create table temp as
          2 select ename
          3 from emp
          4* where deptno=30
          (6) n
          該數(shù)值用于定位sql緩沖區(qū)的當(dāng)前行,示例如下:
          (7)edi[t]
             該命令用于編輯sql緩沖區(qū)的內(nèi)容。當(dāng)運(yùn)行該命令時(shí),在windows平臺中會自動啟動"記事本",以編輯sql緩沖區(qū)
          (8)run和/
             run的/命令都可以用于運(yùn)行sql緩沖區(qū)中的sql語句。注:當(dāng)使用run命令時(shí),還會列出sql緩沖區(qū)內(nèi)容,eg:
             SQL> run
             1* select ename from emp where deptno=20
             4.文件操縱命令
             (1)save
             該命令用于將當(dāng)前sql緩沖區(qū)的內(nèi)容保存到sql腳本中。當(dāng)執(zhí)行該命令時(shí),默認(rèn)選項(xiàng)為create,即建立新文件。
             eg:
             SQL> save c:\a.sql create
             已創(chuàng)建 file c:\a.sql
              當(dāng)執(zhí)行命令之后,就會建立新腳本文件a.sql,并將sql緩沖區(qū)內(nèi)容存放到該文件中。如果sql已經(jīng)存在,使用
             replace選項(xiàng)可以替撚已存在的sql腳本,如果要給已存在的sql腳本追加內(nèi)容,可以使用append選項(xiàng)。
             (2)get
              該命令與save命令作用恰好相反,用于將sql腳本中的所有內(nèi)容裝載到sql緩沖區(qū)中。
              eg:
              SQL> get c:\a.sql
              1* select ename from emp where deptno=20
             (3)start和@
              start和@命令用于運(yùn)行sql腳本文件。注:當(dāng)運(yùn)行sql腳本文件時(shí),應(yīng)該指定文件路徑.eg:
              SQL> @c:\a.sql
              ENAME
              ----------
              SMITH
              JONES
              SCOTT
              ADAMS
              FORD
             (4)@@
              該命令與@命令類似,也可以運(yùn)行腳本文件,但主要作用是在腳本文件中嵌套調(diào)用其它的腳本文件。當(dāng)使用該命令
              嵌套腳本文件時(shí),可在調(diào)用文件所在目錄下查找相應(yīng)文件名。
             (5)ed[it]
              該命令不僅可用于編輯sql緩沖區(qū)內(nèi)容,也可以用于編輯sql腳本文件。當(dāng)運(yùn)行該命令時(shí),會啟動默認(rèn)的系統(tǒng)編輯
              器來編輯sql腳本。運(yùn)行方法為:
              sql>edit c:/a.sql
             (6)spool
              該命令用于將sql*plus屏幕內(nèi)容存放到文本文件中。執(zhí)行該命令時(shí),應(yīng)首先建立假脫機(jī)文件,并將隨后sql*plus
              屏幕的所有內(nèi)容全部存放到該文件中,最后使用spool off命令關(guān)閉假脫機(jī)文件。eg:
              sql>spool c:\a.sql
              5.格式命令
               sql*plus不僅可以用于執(zhí)行sql語句、pl/sql塊,而且還可以根據(jù)select結(jié)果生成報(bào)表。使用sql*plus的格式命令
              可以控制報(bào)表的顯示格式,例如使用column命令可以控制列的顯示格式,使用ttitle命令可以指定頁標(biāo)題;使用
              btitle命令可以指定頁腳注。
              (1)col[umn]
               該命令用于控制列的顯示格式。column命令包含有四個(gè)選項(xiàng),其中clear選項(xiàng)用于清除已定義列的顯示格式:
               heading選項(xiàng)用于指定列的顯示標(biāo)題;justify選項(xiàng)用于指定列標(biāo)題的對齊格式(left,center,right);format選項(xiàng)用于
               指定列的顯示格式,其中格式模型包含以下一些元素。
               An:設(shè)置char,varchar2類型列的顯示寬度;
               9: 在number類型列上禁止顯示前導(dǎo)0;
               0: 在number類型列上強(qiáng)制顯示前導(dǎo)0;
               $: 在number類型列前顯示美元符號;
               L: 在number類型列前顯示本地貨幣符號;
               .: 指定number類型列的小數(shù)點(diǎn)位置;
               ,: 指定number類型列的千分隔符;
              eg1:使用column設(shè)置列顯示格式
               sql>col ename heading 'name' format a10
               sql>col sal heading 'sal' format L99999.99
               sql>select ename,sal,hiredate from emp
               sql>where empno=7788;
               name                       sal HIREDATE
               ---------- ------------------- -------------------
               SCOTT                ¥3000.00 04/19/1987 00:00:00
               sql>col ename clear
               sql>col sal clear
               sql>select ename,sal,hiredate from emp
               sql>where empno=7788;
               (2)title
               該命令用于指定頁標(biāo)題,頁標(biāo)題會自動顯示在頁的中央。如果頁標(biāo)題由多個(gè)詞組成,則用單引號引住。如果要將頁
              標(biāo)題分布在多行顯示,則用"|"分開不同單詞。如果不希望顯示頁標(biāo)題,則使用"ttitle off"命令,禁止顯示,eg:
          SQL> set linesize 40
          SQL> ttitle 'employee report'
          SQL> select ename,sal,hiredate from emp where empno=7788;

          星期二 5月 20                第    1
                      employee report

          ENAME             SAL
          ---------- ----------
          HIREDATE
          -------------------
          SCOTT            3000
          04/19/1987 00:00:00
             (3)btitle
          該命令用于指定頁腳注,頁腳注會自動顯示在頁的中央。如果頁腳注由多個(gè)詞組成,則用單引號引注。如果要將頁腳注
          分布在多行顯示,則用"|"分開不同單詞。如果不希望顯示頁腳注,則使用"btitle off"命令,禁止顯示。eg:
             SQL> btitle 'page end'
             SQL> select ename,sal,hiredate from emp where empno=7788
          ENAME             SAL
          ---------- ----------
          HIREDATE
          -------------------
          SCOTT            3000
          04/19/1987 00:00:00
                   page end
          (4)break
          該命令用于禁止顯示重復(fù)行,并將顯示結(jié)果分隔為幾個(gè)部分,以表現(xiàn)更友好的顯示結(jié)果,通常應(yīng)該在order by 的排序列上
          使用該命令。eg:
          SQL> set pagesize 40
          SQL> break on deptno skip 1
          SQL> select deptno,ename,sal from emp order by deptno
          2 ;

              DEPTNO ENAME             SAL
          ---------- ---------- ----------
                  10 CLARK            2450
                     KING             5000
                     MILLER           1300

                  20 JONES            2975
                     FORD             3000
                     ADAMS            1100
                     SMITH             800
                     SCOTT            3000

                  30 WARD             1250
                     TURNER           1500
                     ALLEN            1600
                     JAMES             950
                     BLAKE            2850
                     MARTIN           1250
             6.交互式命令
              如果經(jīng)常要執(zhí)行某些sql語句和sql*plus命令,可以將這些語句和命令存放到sql腳本中。通過使用sql腳本,
             一方面可以降低命令輸入量,另一方面可以避免用戶的輸入錯(cuò)誤。為了使得sql腳本可以根據(jù)不同輸入獲得
             不同結(jié)果,需要在sql腳本中包含交互式命令。通過使用交互式命令,可以在sql*plus中定義變量,并且在運(yùn)行
             sql腳本時(shí)可以為這些變量動態(tài)輸入數(shù)據(jù)。下面介紹sql*plus的交互命令,以及引用變量所使用的標(biāo)號。
          (1)&
              引用替代變量(substitution variable)時(shí),必須要帶有該標(biāo)號。如果替代變量已經(jīng)定義,則會直接使用其數(shù)據(jù),
              如果替代變量沒有定義,則會臨時(shí)定義替代變量(該替代變量只在當(dāng)前語句中起作用),并需要為其輸入數(shù)據(jù)。
              注:如果替代變量為數(shù)字列則提供數(shù)據(jù),則可以直接引用;如果替代變量為字符類型列或日期類型列提供數(shù)據(jù),
              則必須要用單引號引注。eg:
          SQL> select ename,sal from emp where deptno=&no and job='&job';
          輸入 no 的值: 20
          輸入 job 的值: CLERK
          原值    1: select ename,sal from emp where deptno=&no and job='&job'
          新值    1: select ename,sal from emp where deptno=20 and job='CLERK'
             (2)&&
             該標(biāo)號類似于單個(gè)&標(biāo)號。但需要注意,&標(biāo)號所定義的替代變量只在當(dāng)前語句中起作用;而&&標(biāo)號所定義的變量
          會在當(dāng)前sql*plus環(huán)境中一直生效。eg:
          SQL> select ename,sal from emp where deptno=&&no and job='&&job' --定義了no變量
          輸入 no 的值: 20
          輸入 job 的值: CLERK
          原值    1: select ename,sal from emp where deptno=&&no and job='&&job'
          新值    1: select ename,sal from emp where deptno=20 and job='CLERK'
          SQL> select ename,sal from emp where deptno=&no;           
          原值    1: select ename,sal from emp where deptno=&no             --直接引用no變量
          新值    1: select ename,sal from emp where deptno=20
          ENAME             SAL
          ---------- ----------
          SMITH             800
          JONES            2975
          SCOTT            3000
          ADAMS            1100
          FORD             3000
          如例所示,當(dāng)?shù)谝淮我胣o變量時(shí),使用&&標(biāo)號需要為其輸入數(shù)據(jù);當(dāng)?shù)诙我胣o變量時(shí),
          使用&標(biāo)號直接引用其原有值,而不需要輸入數(shù)據(jù)。
          (3)define
          該命令用于定義類型為char的替代變量,而且該命令的定義的替代變量只在當(dāng)前sql*plus環(huán)境中起作用。
          當(dāng)使用該命令定義變量時(shí),如果變量值包含空格或區(qū)分大小寫,則用引號引注。另外,使用"define變量名"可以檢查變量
          是否已經(jīng)定義。eg:
          sql>set verify off
          sql>define title=CLERK
          sql>select ename,sal from where job='&title';
          (4)accept
          該命令可以用于定義char,number和date類型的替代變量。與define命令相比,accept命令更加靈活。當(dāng)使用該命令定義替代
          變量時(shí),還可以指定變量輸入提示、變量輸入格式、隱藏輸入內(nèi)容。
          eg1:指定變量輸入提示
          SQL> accept title prompt '請輸入崗位:'
          請輸入崗位:CLERK
          SQL> select ename,sal from emp where job='&title';
          原值    1: select ename,sal from emp where job='&title'
          新值    1: select ename,sal from emp where job='CLERK'

          ENAME             SAL
          ---------- ----------
          SMITH             800
          ADAMS            1100
          JAMES             950
          MILLER           1300
          eg2:隱藏用戶輸入
          sql>accept pwd hide
          (5)undefine
          該命令用于清除替代變量的定義。eg:
          sql>undefine pwd
          SQL> disc
          從 Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
          With the Partitioning, OLAP and Data Mining options 斷開
          SQL> conn scott/&pwd
          輸入 pwd 的值: yhai1981
          已連接
          (6)prompt的pause
          prompt命令用于輸出提示信息,而pause命令則用于暫停腳本執(zhí)行。在sql腳本中結(jié)合使用這兩條命令,可以控制sql腳本
          的暫停的執(zhí)行。假定在a.sql腳本中包含以下命令:
          prompt '按<Return>鍵繼續(xù)'
          pause
          當(dāng)運(yùn)行該sql腳本時(shí),會暫停執(zhí)行,eg:
          sql>@c:\a.sql
          '按<Return>鍵繼續(xù)'
          (7)variable
          該命令用于在sql*plus中定義綁定變量。當(dāng)在sql語句或pl/sql塊中引用綁定變量時(shí),必須要在綁定變量前加冒號(:);
          當(dāng)直接給綁定變量賦值時(shí),需要使用execute命令(類似于調(diào)用存儲過程).示例如下:
          sql>var no number
          sql>exec :no:=7788
          sql>select ename from emp where empno=:no;
          ename
          ------------------
          scott
          (8)print
          該命令用于輸出綁定變量結(jié)果,eg:
          SQL> print no

                  NO
          ----------
                7788
          7.顯示和設(shè)置環(huán)境變量
          使用sql*plus的環(huán)境變量可以控制其運(yùn)行環(huán)境,例如設(shè)置行顯示寬度,設(shè)置每頁顯示的行數(shù)、
          設(shè)置自動提交標(biāo)記、設(shè)置自動跟蹤等等。使用show命令可以顯示當(dāng)前sql*plus的環(huán)境變量設(shè)置
          :使用set命令可以修改當(dāng)前sql*plus的環(huán)境變量設(shè)置。下面介紹常用的sql*plus環(huán)境變量。
          (1)顯示所有環(huán)境變量
          為了顯示sql*plus的所有環(huán)境變量,必須要使用show all命令。示例如下:
          SQL> show all
          appinfo 為 OFF 并且已設(shè)置為 "SQL*Plus"
          arraysize 15
          autocommit OFF
          autoprint OFF
          autorecovery OFF
          autotrace OFF
          blockterminator "." (hex 2e)
          btitle OFF 為下一條 SELECT 語句的前幾個(gè)字符
          cmdsep OFF
          colsep " "
          compatibility version NATIVE
          concat "." (hex 2e)
          copycommit 0
          COPYTYPECHECK 為 ON
          define "&" (hex 26)
          describe DEPTH 1 LINENUM OFF INDENT ON
          echo OFF
          editfile "afiedt.buf"
          embedded OFF
          escape OFF
          用于 6 或更多行的 FEEDBACK ON
          flagger OFF
          flush ON
          heading ON
          headsep "|" (hex 7c)
          instance "local"
          linesize 80
          lno 4
          loboffset 1
          logsource ""
          long 80
          longchunksize 80
          markup HTML OFF HEAD "<style type='text/css'> body {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} p {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} table,tr,td {font:10pt Arial,Helvetica,sans-serif; color:Black; background:#f7f7e7; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px;} th {font:bold 10pt Arial,Helvetica,sans-serif; color:#336699; background:#cccc99; padding:0px 0px 0px 0px;} h1 {font:16pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; border-bottom:1px solid #cccc99; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;} h2 {font:bold 10pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; margin-top:4pt; margin-bottom:0pt;} a {font:9pt Arial,Helvetica,sans-serif; color:#663300; background:#ffffff; margin-top:0pt; margin-bottom:0pt; vertical-align:top;}</style><title>SQL*Plus Report</title>" BODY "" TABLE "border='1' width='90%' align='center' summary='Script output'" SPOOL OFF ENTMAP ON PREFORMAT OFF
          newpage 1
          null ""
          numformat ""
          numwidth 10
          pagesize 14
          PAUSE 為 OFF
          pno 1
          recsep WRAP
          recsepchar " " (hex 20)
          release 1002000100
          repfooter OFF 為 NULL
          repheader OFF 為 NULL
          serveroutput OFF
          shiftinout INVISIBLE
          showmode OFF
          spool ON
          sqlblanklines OFF
          sqlcase MIXED
          sqlcode 0
          sqlcontinue "> "
          sqlnumber ON
          sqlpluscompatibility 10.2.0
          sqlprefix "#" (hex 23)
          sqlprompt "SQL> "
          sqlterminator ";" (hex 3b)
          suffix "sql"
          tab ON
          termout ON
          timing OFF
          trimout ON
          trimspool OFF
          ttitle OFF 為下一條 SELECT 語句的前幾個(gè)字符
          underline "-" (hex 2d)
          USER 為 "SCOTT"
          verify ON
          wrap : 將換至下一行
          SQL> spool off

          (2)arraysize
          該環(huán)境變量用于指定數(shù)組提取尺寸,其默認(rèn)值為15.該值越大,網(wǎng)絡(luò)開銷將會越低,但占用內(nèi)存會增加。假定使用默認(rèn)值,
          如果查詢返回行數(shù)為50行,則需要通過網(wǎng)絡(luò)傳送4將數(shù)據(jù);如果設(shè)置為25,則網(wǎng)絡(luò)傳送次數(shù)只有兩次。eg:

          SQL> show arraysize
          arraysize 15
          SQL> set arraysize 25
          (3)autocommit
          該環(huán)境變量用于設(shè)置是否自動提交dml語句,其默認(rèn)值為off(表示禁止自動提交)。當(dāng)設(shè)置為ON時(shí),每次執(zhí)行DML
          語句都會自動提交。eg:
          SQL> show autocommit
          autocommit OFF
          SQL> set autocommit on
          SQL> show autocommit
          autocommit IMMEDIATE
          (4)colsep
          該環(huán)境變量用于設(shè)置列之間的分隔符,默認(rèn)分隔符為空格。如果要使用其它分隔符,則使用set命令進(jìn)行設(shè)置。eg:
          sql>set colsep |  
          SQL> select ename,sal from emp where empno=7788

          ENAME     |       SAL
          ----------|----------
          SCOTT     |      3000
          (5)feedback
          該環(huán)境變量用于指定顯示反饋行數(shù)信息的最低行數(shù),其默認(rèn)值為6。如果要禁止顯示行數(shù)反饋信息,則將feedback
          設(shè)置為off。假設(shè)只要有查詢結(jié)果就返回行數(shù),那么可以將該環(huán)境變量設(shè)置為1.eg:
          sql>set feedback 1
          sql>select ename,sal from emp where empno=7788;

          ENAME     |       SAL
          ----------|----------
          SCOTT     |      3000
          已選擇 1 行。
          (6)heading
          該環(huán)境變量用于設(shè)置是否顯示標(biāo)題,其默認(rèn)值為on。如果不顯示列標(biāo)題,則設(shè)置為off。eg:
          sql>set heading off
          sql>select ename,sal from emp where empno=7788
          SCOTT     |      3000
          (7)linesize
          該環(huán)境變量用于設(shè)置行寬度,默認(rèn)值為80。在默認(rèn)情況下,如果數(shù)據(jù)長度超過80個(gè)字符,那么在sql*plus中會折
          行顯示數(shù)據(jù)結(jié)果。要在一行中顯示全部數(shù)據(jù),應(yīng)該設(shè)置更大的值。eg:
          (8)pagesize
          該環(huán)境變量用于設(shè)置每頁所顯示的行數(shù),默認(rèn)值為14
          set pagesize 0;   //輸出每頁行數(shù),缺省為24,為了避免分頁,可設(shè)定為0。
          (9)long
          該環(huán)境變量用于設(shè)置long和lob類型列的顯示長度。默認(rèn)值為80,也就是說當(dāng)查詢long或lob列時(shí),只會顯示該列的前80個(gè)字符,
          應(yīng)該設(shè)置更大的值。eg:
          sql>show long
          long 80
          sql>set long 300
          (10)serveroutput
          該環(huán)境變量用于控制服務(wù)器輸出,其默認(rèn)值為off,表示禁止服務(wù)器輸出。在默認(rèn)情況下,當(dāng)調(diào)用dbms_output包時(shí),
          不會在sql*plus屏幕上顯示輸出結(jié)果。在調(diào)用dbms_output包時(shí),為了在屏幕上輸出結(jié)果,必須要將serveroutput設(shè)置
          為on。eg:
          sql>set serveroutput on
          sql>exec dbms_output.put_line('hello')
          (11)termout
          該環(huán)境變量用于控制sql腳本的輸出,其默認(rèn)值為ON。當(dāng)使用默認(rèn)值時(shí),如果sql腳本有輸出結(jié)果,則會在屏幕上輸出
          顯示結(jié)果,如果設(shè)置為OFF,則不會在屏幕上輸出sql腳本。eg:
          SQL> set termout off
          SQL> @c:\a
          (12)time
          該環(huán)境變量用于設(shè)置在sql提示符前是否顯示系統(tǒng)時(shí)間,默認(rèn)值為off,表示禁止顯示系統(tǒng)時(shí)間。如果設(shè)置為on,
          則在sql提示符前會顯示系統(tǒng)時(shí)間.eg:
          SQL> set time on
          12:09:59 SQL>
          (13)timing
          該環(huán)境變量用于設(shè)置是否要顯示sql語句執(zhí)行時(shí)間,默認(rèn)值為off,表示不會顯示sql語句執(zhí)行時(shí)間。如果設(shè)置為
          ON,則會顯示sql語句執(zhí)行時(shí)間。eg:
          sql>set timing on
          SQL> select count(*) from emp;

          COUNT(*)
          ----------
                  14

          已選擇 1 行。

          已用時(shí)間: 00: 00: 00.03
          (14)trimspool
          set trimout on;   //去除標(biāo)準(zhǔn)輸出每行的拖尾空格,缺省為off
          set trimspool on;  //去除重定向(spool)輸出每行的拖尾空格,缺省為off

          如果trimspool設(shè)置為on,將移除spool文件中的尾部空格 ,trimout同trimspool功能相似,只不過對象是控制臺。
          If trimspool is set to on, it will remove trailing blanks in spooled files.
          See also trimout which does the same thing to the output to the console (terminal).
          eg:
          set trimspool off
          spool c:\temp\trimspool.txt
          declare
          v_name varchar2(30);
          begin
          SELECT table_name into v_name
          FROM all_tables
          WHERE rownum =1;
          dbms_output.put_line(v_name);
          end;
          /
          set trimspool on
          declare
          v_name varchar2(30);
          begin
          SELECT table_name into v_name
          FROM all_tables
          WHERE rownum =1;
          dbms_output.put_line(v_name);
          end;
          /
          spool off

          -- from ITPUB

          文章來源:http://blog.163.com/ccbobo_cat/blog/static/32099462200932325331787
          posted @ 2009-04-23 14:54 C.B.K 閱讀(1405) | 評論 (0)編輯 收藏
          如果機(jī)房馬上要關(guān)門了,或者你急著要和MM約會,請直接跳到第六個(gè)自然段。

               我們這里說的KMP不是拿來放電影的(雖然我很喜歡這個(gè)軟件),而是一種算法。KMP算法是拿來處理字符串匹配的。換句話說,給你兩個(gè)字符串,你需要回 答,B串是否是A串的子串(A串是否包含B串)。比如,字符串A="I'm matrix67",字符串B="matrix",我們就說B是A的子串。你可以委婉地問你的MM:“假如你要向你喜歡的人表白的話,我的名字是你的告白 語中的子串嗎?”
               解決這類問題,通常我們的方法是枚舉從A串的什么位置起開始與B匹配,然后驗(yàn)證是否匹配。假如A串長度為n,B串長度為m,那么這種方法的復(fù)雜度是O (mn)的。雖然很多時(shí)候復(fù)雜度達(dá)不到mn(驗(yàn)證時(shí)只看頭一兩個(gè)字母就發(fā)現(xiàn)不匹配了),但我們有許多“最壞情況”,比如,A= "aaaaaaaaaaaaaaaaaaaaaaaaaab",B="aaaaaaaab"。我們將介紹的是一種最壞情況下O(n)的算法(這里假設(shè) m<=n),即傳說中的KMP算法。
               之所以叫做KMP,是因?yàn)檫@個(gè)算法是由Knuth、Morris、Pratt三個(gè)提出來的,取了這三個(gè)人的名字的頭一個(gè)字母。這時(shí),或許你突然明白了 AVL 樹為什么叫AVL,或者Bellman-Ford為什么中間是一杠不是一個(gè)點(diǎn)。有時(shí)一個(gè)東西有七八個(gè)人研究過,那怎么命名呢?通常這個(gè)東西干脆就不用人名 字命名了,免得發(fā)生爭議,比如“3x+1問題”。扯遠(yuǎn)了。
               個(gè)人認(rèn)為KMP是最沒有必要講的東西,因?yàn)檫@個(gè)東西網(wǎng)上能找到很多資料。但網(wǎng)上的講法基本上都涉及到“移動(shift)”、“Next函數(shù)”等概念,這 非常容易產(chǎn)生誤解(至少一年半前我看這些資料學(xué)習(xí)KMP時(shí)就沒搞清楚)。在這里,我換一種方法來解釋KMP算法。

               假如,A="abababaababacb",B="ababacb",我們來看看KMP是怎么工作的。我們用兩個(gè)指針i和j分別表示,A[i-j+ 1..i]與B[1..j]完全相等。也就是說,i是不斷增加的,隨著i的增加j相應(yīng)地變化,且j滿足以A[i]結(jié)尾的長度為j的字符串正好匹配B串的前 j個(gè)字符(j當(dāng)然越大越好),現(xiàn)在需要檢驗(yàn)A[i+1]和B[j+1]的關(guān)系。當(dāng)A[i+1]=B[j+1]時(shí),i和j各加一;什么時(shí)候j=m了,我們就 說B是A的子串(B串已經(jīng)整完了),并且可以根據(jù)這時(shí)的i值算出匹配的位置。當(dāng)A[i+1]<>B[j+1],KMP的策略是調(diào)整j的位置 (減小j值)使得A[i-j+1..i]與B[1..j]保持匹配且新的B[j+1]恰好與A[i+1]匹配(從而使得i和j能繼續(xù)增加)。我們看一看當(dāng) i=j=5時(shí)的情況。

               i   = 1 2 3 4 5 6 7 8 9 ……
               A = a b a b a b a a b a b …
               B = a b a b a c b
               j =   1 2 3 4 5 6 7


               此時(shí),A[6]<>B[6]。這表明,此時(shí)j不能等于5了,我們要把j改成比它小的值j'。j'可能是多少呢?仔細(xì)想一下,我們發(fā)現(xiàn),j'必 須要使得B[1..j]中的頭j'個(gè)字母和末j'個(gè)字母完全相等(這樣j變成了j'后才能繼續(xù)保持i和j的性質(zhì))。這個(gè)j'當(dāng)然要越大越好。在這里,B [1..5]="ababa",頭3個(gè)字母和末3個(gè)字母都是"aba"。而當(dāng)新的j為3時(shí),A[6]恰好和B[4]相等。于是,i變成了6,而j則變成了 4:

               i   = 1 2 3 4 5 6 7 8 9 ……
               A = a b a b a b a a b a b …
               B =       a b a b a c b
               j =         1 2 3 4 5 6 7


               從上面的這個(gè)例子,我們可以看到,新的j可以取多少與i無關(guān),只與B串有關(guān)。我們完全可以預(yù)處理出這樣一個(gè)數(shù)組P[j],表示當(dāng)匹配到B數(shù)組的第j個(gè)字母 而第j+1個(gè)字母不能匹配了時(shí),新的j最大是多少。P[j]應(yīng)該是所有滿足B[1..P[j]]=B[j-P[j]+1..j]的最大值。
               再后來,A[7]=B[5],i和j又各增加1。這時(shí),又出現(xiàn)了A[i+1]<>B[j+1]的情況:

               i   = 1 2 3 4 5 6 7 8 9 ……
               A = a b a b a b a a b a b …
               B =       a b a b a c b
               j =        1 2 3 4 5 6 7


               由于P[5]=3,因此新的j=3:

               i = 1 2 3 4 5 6 7 8 9 ……
               A = a b a b a b a a b a b …
               B =             a b a b a c b
               j =              1 2 3 4 5 6 7


               這時(shí),新的j=3仍然不能滿足A[i+1]=B[j+1],此時(shí)我們再次減小j值,將j再次更新為P[3]:

               i = 1 2 3 4 5 6 7 8 9 ……
               A = a b a b a b a a b a b …
               B =                   a b a b a c b
               j =                    1 2 3 4 5 6 7


               現(xiàn)在,i還是7,j已經(jīng)變成1了。而此時(shí)A[8]居然仍然不等于B[j+1]。這樣,j必須減小到P[1],即0:

               i = 1 2 3 4 5 6 7 8 9 ……
               A = a b a b a b a a b a b …
               B =                      a b a b a c b
               j =                    0 1 2 3 4 5 6 7


               終于,A[8]=B[1],i變?yōu)?,j為1。事實(shí)上,有可能j到了0仍然不能滿足A[i+1]=B[j+1](比如A[8]="d"時(shí))。因此,準(zhǔn)確的說法是,當(dāng)j=0了時(shí),我們增加i值但忽略j直到出現(xiàn)A[i]=B[1]為止。
               這個(gè)過程的代碼很短(真的很短),我們在這里給出:

          程序代碼
          j:=0;
          for i:=1 to n do
          begin
             while (j>0) and (B[j+1]<>A[i]) do j:=P[j];
             if B[j+1]=A[i] then j:=j+1;
             if j=m then
             begin
                 writeln('Pattern occurs with shift ',i-m);
                 j:=P[j];
             end;
          end;


               最后的j:=P[j]是為了讓程序繼續(xù)做下去,因?yàn)槲覀冇锌赡苷业蕉嗵幤ヅ洹?br>      這個(gè)程序或許比想像中的要簡單,因?yàn)閷τ趇值的不斷增加,代碼用的是for循環(huán)。因此,這個(gè)代碼可以這樣形象地理解:掃描字符串A,并更新可以匹配到B的什么位置。

               現(xiàn)在,我們還遺留了兩個(gè)重要的問題:一,為什么這個(gè)程序是線性的;二,如何快速預(yù)處理P數(shù)組。
               為什么這個(gè)程序是O(n)的?其實(shí),主要的爭議在于,while循環(huán)使得執(zhí)行次數(shù)出現(xiàn)了不確定因素。我們將用到時(shí)間復(fù)雜度的攤還分析中的主要策略,簡單地 說就是通過觀察某一個(gè)變量或函數(shù)值的變化來對零散的、雜亂的、不規(guī)則的執(zhí)行次數(shù)進(jìn)行累計(jì)。KMP的時(shí)間復(fù)雜度分析可謂攤還分析的典型。我們從上述程序的j 值入手。每一次執(zhí)行while循環(huán)都會使j減小(但不能減成負(fù)的),而另外的改變j值的地方只有第五行。每次執(zhí)行了這一行,j都只能加1;因此,整個(gè)過程 中j最多加了n個(gè)1。于是,j最多只有n次減小的機(jī)會(j值減小的次數(shù)當(dāng)然不能超過n,因?yàn)閖永遠(yuǎn)是非負(fù)整數(shù))。這告訴我們,while循環(huán)總共最多執(zhí)行 了n次。按照攤還分析的說法,平攤到每次for循環(huán)中后,一次for循環(huán)的復(fù)雜度為O(1)。整個(gè)過程顯然是O(n)的。這樣的分析對于后面P數(shù)組預(yù)處理 的過程同樣有效,同樣可以得到預(yù)處理過程的復(fù)雜度為O(m)。
               預(yù)處理不需要按照P的定義寫成O(m^2)甚至O(m^3)的。我們可以通過P[1],P[2],...,P[j-1]的值來獲得P[j]的值。對于剛才 的B="ababacb",假如我們已經(jīng)求出了P[1],P[2],P[3]和P[4],看看我們應(yīng)該怎么求出P[5]和P[6]。P[4]=2,那么P [5]顯然等于P[4]+1,因?yàn)橛蒔[4]可以知道,B[1,2]已經(jīng)和B[3,4]相等了,現(xiàn)在又有B[3]=B[5],所以P[5]可以由P[4] 后面加一個(gè)字符得到。P[6]也等于P[5]+1嗎?顯然不是,因?yàn)锽[ P[5]+1 ]<>B[6]。那么,我們要考慮“退一步”了。我們考慮P[6]是否有可能由P[5]的情況所包含的子串得到,即是否P[6]=P[ P[5] ]+1。這里想不通的話可以仔細(xì)看一下:

                   1 2 3 4 5 6 7
               B = a b a b a c b
               P = 0 0 1 2 3 ?


               P[5]=3是因?yàn)锽[1..3]和B[3..5]都是"aba";而P[3]=1則告訴我們,B[1]和B[5]都是"a"。既然P[6]不能由P [5]得到,或許可以由P[3]得到(如果B[2]恰好和B[6]相等的話,P[6]就等于P[3]+1了)。顯然,P[6]也不能通過P[3]得到,因 為B[2]<>B[6]。事實(shí)上,這樣一直推到P[1]也不行,最后,我們得到,P[6]=0。
               怎么這個(gè)預(yù)處理過程跟前面的KMP主程序這么像呢?其實(shí),KMP的預(yù)處理本身就是一個(gè)B串“自我匹配”的過程。它的代碼和上面的代碼神似:

          程序代碼
          P[1]:=0;
          j:=0;
          for i:=2 to m do
          begin
             while (j>0) and (B[j+1]<>B[i]) do j:=P[j];
             if B[j+1]=B[i] then j:=j+1;
             P[i]:=j;
          end;


               最后補(bǔ)充一點(diǎn):由于KMP算法只預(yù)處理B串,因此這種算法很適合這樣的問題:給定一個(gè)B串和一群不同的A串,問B是哪些A串的子串。

               串匹配是一個(gè)很有研究價(jià)值的問題。事實(shí)上,我們還有后綴樹,自動機(jī)等很多方法,這些算法都巧妙地運(yùn)用了預(yù)處理,從而可以在線性的時(shí)間里解決字符串的匹配。我們以后來說。

          Matrix67原創(chuàng)


          文章來源:http://blog.163.com/ccbobo_cat/blog/static/32099462200931645748543
          posted @ 2009-04-16 16:58 C.B.K 閱讀(80) | 評論 (0)編輯 收藏
          (1)給金額添加逗號
          import java.text.*;
          NumberFormat formater = new DecimalFormat("###,###.##");
          formater.format(12342351432534.24565);
          (2)日期格式換
          Date now = new Date();
          SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
          formater.format(now());
          SimpleDateFormat

          模式字母(所有其他字符 'A''Z''a''z' 都被保留):

          字母 日期或時(shí)間元素 表示 示例
          G Era 標(biāo)志符 Text AD
          y Year 1996; 96
          M 年中的月份 Month July; Jul; 07
          w 年中的周數(shù) Number 27
          W 月份中的周數(shù) Number 2
          D 年中的天數(shù) Number 189
          d 月份中的天數(shù) Number 10
          F 月份中的星期 Number 2
          E 星期中的天數(shù) Text Tuesday; Tue
          a Am/pm 標(biāo)記 Text PM
          H 一天中的小時(shí)數(shù)(0-23) Number 0
          k 一天中的小時(shí)數(shù)(1-24) Number 24
          K am/pm 中的小時(shí)數(shù)(0-11) Number 0
          h am/pm 中的小時(shí)數(shù)(1-12) Number 12
          m 小時(shí)中的分鐘數(shù) Number 30
          s 分鐘中的秒數(shù) Number 55
          S 毫秒數(shù) Number 978
          z 時(shí)區(qū) General time zone Pacific Standard Time; PST; GMT-08:00
          Z 時(shí)區(qū) RFC 822 time zone -0800
          模式字母通常是重復(fù)的,其數(shù)量確定其精確表示:
          • Text: 對于格式化來說,如果模式字母的數(shù)量大于或等于 4,則使用完全形式;否則,在可用的情況下使用短形式或縮寫形式。對于分析來說,兩種形式都是可接受的,與模式字母的數(shù)量無關(guān)。
          • Number: 對于格式化來說,模式字母的數(shù)量是最小的數(shù)位,如果數(shù)位不夠,則用 0 填充以達(dá)到此數(shù)量。對于分析來說,模式字母的數(shù)量被忽略,除非必須分開兩個(gè)相鄰字段。
          • Year: 對于格式化來說,如果模式字母的數(shù)量為 2,則年份截取為 2 位數(shù),否則將年份解釋為 number。 SimpleDateFormat

            示例

            以下示例顯示了如何在美國語言環(huán)境中解釋日期和時(shí)間模式。給定的日期和時(shí)間為美國太平洋時(shí)區(qū)的本地時(shí)間 2001-07-04 12:08:56。
            日期和時(shí)間模式 結(jié)果
            "yyyy.MM.dd G 'at' HH:mm:ss z" 2001.07.04 AD at 12:08:56 PDT
            "EEE, MMM d, ''yy" Wed, Jul 4, '01
            "h:mm a" 12:08 PM
            "hh 'o''clock' a, zzzz" 12 o'clock PM, Pacific Daylight Time
            "K:mm a, z" 0:08 PM, PDT
            "yyyyy.MMMMM.dd GGG hh:mm aaa" 02001.July.04 AD 12:08 PM
            "EEE, d MMM yyyy HH:mm:ss Z" Wed, 4 Jul 2001 12:08:56 -0700
            "yyMMddHHmmssZ" 010704120856-0700
            "yyyy-MM-dd'T'HH:mm:ss.SSSZ" 2001-07-04T12:08:56.235-0700


          文章來源:http://blog.163.com/ccbobo_cat/blog/static/32099462200931621628957
          posted @ 2009-04-16 14:16 C.B.K 閱讀(85) | 評論 (0)編輯 收藏

          (一)

          開門見山.今天我要說的是不用HQL執(zhí)行SAVE和DELETE方法,用hibernate的executeQuery來執(zhí)行SQL

          其原理如下(從SessionFactory里獲得個(gè)Session,在調(diào)用session的connection方法,通過Statement來執(zhí)行靜態(tài)SQL,最后執(zhí)行executeQuery就可以了)具體如下:

          protected Session session = null; protected Transaction tr = null;

          String sql = "insert into as_dept2role(roleid,dept_id)value('"+roleId+"','"+deptId+"')"; session=HibernateSessionFactory.getSession();                                                                               

             session.beginTransaction();
          //獲取connection,執(zhí)行靜態(tài)SQL
          Statement state = session.connection().createStatement();
          state.executeQuery(sql);
          tr.commit(); session.close();

          當(dāng)然關(guān)于 關(guān)閉SESSION 這些方法我寫的簡單些,主要是為了寫 執(zhí)行SQL這些方法

          對于刪除只要寫個(gè)刪除語句就可以了

          :Transaction tr = session.beginTransaction();

          * session.connection() 方法過時(shí) 用下面來代替 *
          DataSource ds= SessionFactoryUtils.getDataSource(getSessionFactory());
          conn=ds.getConnection();

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

          (二)

          public Object get(Class cls, String szId) {
          Object obj = this.getHibernateTemplate().get(cls, szId);
          return obj;
          }
          obj.getsessionFaction.opensession返回session


          Session session = dao.openSession();
          Connection conn = session.connection();
          List recordList = new ArrayList();

          StringBuffer sql = new StringBuffer();
          sql.append("select b.user_name, c.org_name ");
          sql.append("from orgmeetinglinkman a, am_user b, organization c ");
          sql.append("where a.login_name = b.login_name ");
          sql.append("and a.org_id = c.org_id ");

          PreparedStatement ps = conn.prepareStatement(sql.toString());
          ResultSet rs = ps.execu

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

          (三)

          public List findWithSQL(final String sql) {
             List list = (List) this.getHibernateTemplate().execute(
               new HibernateCallback() {
                public Object doInHibernate(Session session)
                  throws SQLException, HibernateException {
                 SQLQuery query = session.createSQLQuery(sql);
                 query.addScalar("NX",new org.hibernate.type.StringType());
                 List children = query.list();
                 return children;
                }
               });
             return list;
          }

          /**
          * 查詢并返回結(jié)果集,結(jié)果集中的內(nèi)容已經(jīng)都轉(zhuǎn)為了字符串
          */
          public List<List<String>> findSql(final String sql) {
             // TODO Auto-generated method stub
             System.out.println("findSql---sql1----->"+sql);
             List<List<String>> mainObjList= (List<List<String>>) getHibernateTemplate().execute(new HibernateCallback() {

              public Object doInHibernate(Session session)
                throws HibernateException, SQLException {

              
               int n=-1;
               Connection con=null;
               PreparedStatement stmt=null;
               ResultSet rs=null;
              
               try
               {
               
                DataSource ds= SessionFactoryUtils.getDataSource(getSessionFactory());
                if(ds==null)
                {
                 throw new SQLException("get dataSource is null");
                }
                con=ds.getConnection();
                System.out.println("findSql---sql2----->"+sql);
                stmt=con.prepareStatement(sql);
                rs=stmt.executeQuery();
               
               } catch (HibernateException e)
               {
                // TODO Auto-generated catch block
                e.printStackTrace();
               } catch (SQLException e)
               {
                // TODO Auto-generated catch block
                e.printStackTrace();
               }
              
               List<List<String>> list=new ArrayList<List<String>>();//每行為一個(gè)list
               try
               {
                ResultSetMetaData rsmd=rs.getMetaData();
                int colsNum=rsmd.getColumnCount();//取得列數(shù)
                int rsNum=0;
                while(rs.next())
                {
                 rsNum++;
                 System.out.println("rsNum==="+rsNum+" ");
                 List<String> subList=new ArrayList<String> ();//每列的類型為string
                 for(int i=1;i<=colsNum;i++)
                 {
                  System.out.println("\ti==="+i);
                  //int type= rsmd.getColumnType(i);
                  String columnType=getDataType(rsmd.getColumnType(i),rsmd.getScale(i));  
                  String val="";
                  if(columnType.equalsIgnoreCase("Date"))
                  {
                   Timestamp timest= rs.getTimestamp(i);
                   if(timest!=null)
                   {
                    long times=timest.getTime();
                    Date date=new Date(times);
                    SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.CHINA);
                    val=df.format(date);
                   }
                  }
                  else if(columnType.equalsIgnoreCase("Number"))
                  {
                   Object obj=rs.getObject(i);
                   if(obj!=null)
                   {
                    int m=rs.getInt(i);
                    val=Integer.toString(m);
                   }
                  }
                  else if(columnType.equalsIgnoreCase("blob"))
                  {
                   val="不支持blob數(shù)據(jù)的讀取";
                  }
                  else if(columnType.equalsIgnoreCase("clob"))
                  {
                   val=getOracleClobField(rs, i);
                  
                  }
                  else
                  {
                   val=rs.getString(i);
                  }
                  if(val==null)
                  {
                   val="";
                  }
                  subList.add(val);
                 }
                 if(subList.size()>0)
                 {
                  list.add(subList);
                 }
                }
               }
               catch(Exception ex5)
               {
                ex5.printStackTrace();
                System.out.println("ex5.getMessage="+ex5.getMessage());
                list=null;
               }
               finally
               {
                try {
                 if (rs != null) {
                  rs.close();
                  rs = null;
                 }
                } catch (Exception e2) {
                 // TODO: handle exception
                 e2.printStackTrace();
                 System.out.println("e2.getMessage="+e2.getMessage());
                }
                try {
                 if (stmt != null) {
                  stmt.close();
                  stmt = null;
                 }
                } catch (Exception e3) {
                 // TODO: handle exception
                 e3.printStackTrace();
                 System.out.println("e3.getMessage="+e3.getMessage());
                }
                try {
                 if (con != null) {
                  con.close();
                  con = null;
                 }
                } catch (Exception e4) {
                 // TODO: handle exception
                 e4.printStackTrace();
                 System.out.println("e4.getMessage="+e4.getMessage());
                }
               
               }
               return list;
              }

             });
             return mainObjList;
          }

          // String   columnType=getDataType(rmd.getColumnType(i),rmd.getScale(i));  
          private String getOracleClobField(ResultSet rset, int index)
               throws Exception
          {
               StringBuffer buffS = new StringBuffer();
               Clob clob = rset.getClob(index + 1);
               if(clob == null)
                   return " ";
               Reader reader = clob.getCharacterStream();
               char buff[] = new char[1024];
               for(int len = 0; (len = reader.read(buff)) != -1;)
                   buffS.append(buff, 0, len);
                return buffS.toString();
          }
              
          private   static   String   getDataType(int   type,int   scale)
          {  
             String   dataType="";  

             switch(type){  
              case   Types.LONGVARCHAR:   //-1  
               dataType="Long";  
                break;  
              case   Types.CHAR:         //1  
               dataType="Character";  
                    break;  
              case   Types.NUMERIC:   //2  
               switch(scale)
               {  
                   case   0:  
                       dataType="Number";  
                       break;  
                   case   -127:  
                       dataType="Float";  
                       break;  
                   default:  
                       dataType="Number";  
               }  
               break;  
              case   Types.VARCHAR:     //12  
               dataType="String";  
                  break;  
              case   Types.DATE:     //91  
               dataType="Date";  
                  break;  
              case   Types.TIMESTAMP:   //93  
               dataType="Date";  
                  break;  
              case   Types.BLOB   :  
                  dataType="Blob";  
                  break;  
              default:  
                  dataType="String";  
              }  
              return   dataType;
          }


          文章來源:http://blog.163.com/ccbobo_cat/blog/static/32099462200931511221288
          posted @ 2009-04-15 23:22 C.B.K 閱讀(18793) | 評論 (1)編輯 收藏
            匈牙利命名法
            匈牙利命名法是一種編程時(shí)的命名規(guī)范。基本原則是:變量名=屬性+類型+對象描述,其中每一對象的名稱都要求有明確含義,可以取對象名字全稱或名字的一部分。命名要基于容易記憶容易理解的原則。保證名字的連貫性是非常重要的。
            舉例來說,表單的名稱為form,那么在匈牙利命名法中可以簡寫為frm,則當(dāng)表單變量名稱為 Switchboard時(shí),變量全稱應(yīng)該為 frmSwitchboard。這樣可以很容易從變量名看出Switchboard是一個(gè)表單,同樣,如果此變量類型為標(biāo)簽,那么就應(yīng)命名成 lblSwitchboard。可以看出,匈牙利命名法非常便于記憶,而且使變量名非常清晰易懂,這樣,增強(qiáng)了代碼的可讀性,方便各程序員之間相互交流代 碼。
            據(jù)說這種命名法是一位叫 Charles Simonyi 的匈牙利程序員發(fā)明的,后來他在微軟呆了幾年,于是這種命名法就通過微軟的各種產(chǎn)品和文檔資料向世界傳播開了。現(xiàn)在,大部分程序員不管自己使用什么軟件進(jìn) 行開發(fā),或多或少都使用了這種命名法。這種命名法的出發(fā)點(diǎn)是把變量名按:屬性+類型+對象描述的順序組合起來,以使程序員作變量時(shí)對變量的類型和其它屬性 有直觀的了解,下面是HN變量命名規(guī)范,其中也有一些是我個(gè)人的偏向:
            屬性部分
            全局變量
            g_
            常量
            c_
            c++類成員變量
            m_
            靜態(tài)變量
            s_
            類型部分
            指針
            p
            函數(shù)
            fn
            無效
            v
            句柄
            h
            長整型
            l
            布爾
            b
            浮點(diǎn)型(有時(shí)也指文件)
            f
            雙字
            dw
            字符串
            sz
            短整型
            n
            雙精度浮點(diǎn)
            d
            計(jì)數(shù)
            c(通常用cnt)
            字符
            ch(通常用c)
            整型
            i(通常用n)
            字節(jié)
            by
            字
            w
            實(shí)型
            r
            無符號
            u
            描述部分
            最大
            Max
            最小
            Min
            初始化
            Init
            臨時(shí)變量
            T(或Temp)
            源對象
            Src
            目的對象
            Dest
            這里順便寫幾個(gè)例子:
            hwnd : h 是類型描述,表示句柄, wnd 是變量對象描述,表示窗口,所以 hwnd 表示窗口句柄;
            pfnEatApple : pfn 是類型描述,表示指向函數(shù)的指針, EatApple 是變量對象描述,所以它表示
            指向 EatApple 函數(shù)的函數(shù)指針變量。
            g_cch : g_ 是屬性描述,表示全局變量,c 和 ch 分別是計(jì)數(shù)類型和字符類型,一起表示變量類
            型,這里忽略了對象描述,所以它表示一個(gè)對字符進(jìn)行計(jì)數(shù)的全局變量。
            上面就是HN命名法的一般規(guī)則。
            小結(jié):匈牙利命名法
            匈牙利命名法
            MFC、句柄、控件及結(jié)構(gòu)的命名規(guī)范 Windows類型 樣本變量 MFC類 樣本變量
            HWND hWnd; CWnd* pWnd;
            HDLG hDlg; CDialog* pDlg;
            HDC hDC; CDC* pDC;
            HGDIOBJ hGdiObj; CGdiObject* pGdiObj;
            HPEN hPen; CPen* pPen;
            HBRUSH hBrush; CBrush* pBrush;
            HFONT hFont; CFont* pFont;
            HBITMAP hBitmap; CBitmap* pBitmap;
            HPALETTE hPaltte; CPalette* pPalette;
            HRGN hRgn; CRgn* pRgn;
            HMENU hMenu; CMenu* pMenu;
            HWND hCtl; CState* pState;
            HWND hCtl; CButton* pButton;
            HWND hCtl; CEdit* pEdit;
            HWND hCtl; CListBox* pListBox;
            HWND hCtl; CComboBox* pComboBox;
            HWND hCtl; CScrollBar* pScrollBar;
            HSZ hszStr; CString pStr;
            POINT pt; CPoint pt;
            SIZE size; CSize size;
            RECT rect; CRect rect;
            一般前綴命名規(guī)范 前綴 類型 實(shí)例
            C 類或結(jié)構(gòu) CDocument,CPrintInfo
            m_ 成員變量 m_pDoc,m_nCustomers
            變量命名規(guī)范 前綴 類型 描述 實(shí)例
            ch char 8位字符 chGrade
            ch TCHAR 如果_UNICODE定義,則為16位字符 chName
            b BOOL 布爾值 bEnable
            n int 整型(其大小依賴于操作系統(tǒng)) nLength
            n UINT 無符號值(其大小依賴于操作系統(tǒng)) nHeight
            w WORD 16位無符號值 wPos
            l LONG 32位有符號整型 lOffset
            dw DWORD 32位無符號整型 dwRange
            p * 指針 pDoc
            lp FAR* 遠(yuǎn)指針 lpszName
            lpsz LPSTR 32位字符串指針 lpszName
            lpsz LPCSTR 32位常量字符串指針 lpszName
            lpsz LPCTSTR 如果_UNICODE定義,則為32位常量字符串指針 lpszName
            h handle Windows對象句柄 hWnd
            lpfn callback 指向CALLBACK函數(shù)的遠(yuǎn)指針
            前綴 符號類型 實(shí)例 范圍
            IDR_ 不同類型的多個(gè)資源共享標(biāo)識 IDR_MAIINFRAME 1~0x6FFF
            IDD_ 對話框資源 IDD_SPELL_CHECK 1~0x6FFF
            HIDD_ 對話框資源的Help上下文 HIDD_SPELL_CHECK 0x20001~0x26FF
            IDB_ 位圖資源 IDB_COMPANY_LOGO 1~0x6FFF
            IDC_ 光標(biāo)資源 IDC_PENCIL 1~0x6FFF
            IDI_ 圖標(biāo)資源 IDI_NOTEPAD 1~0x6FFF
            ID_ 來自菜單項(xiàng)或工具欄的命令 ID_TOOLS_SPELLING 0x8000~0xDFFF
            HID_ 命令Help上下文 HID_TOOLS_SPELLING 0x18000~0x1DFFF
            IDP_ 消息框提示 IDP_INVALID_PARTNO 8~0xDEEF
            HIDP_ 消息框Help上下文 HIDP_INVALID_PARTNO 0x30008~0x3DEFF
            IDS_ 串資源 IDS_COPYRIGHT 1~0x7EEF
            IDC_ 對話框內(nèi)的控件 IDC_RECALC 8~0xDEEF
            Microsoft MFC宏命名規(guī)范 名稱 類型
            _AFXDLL 唯一的動態(tài)連接庫(Dynamic Link Library,DLL)版本
            _ALPHA 僅編譯DEC Alpha處理器
            _DEBUG 包括診斷的調(diào)試版本
            _MBCS 編譯多字節(jié)字符集
            _UNICODE 在一個(gè)應(yīng)用程序中打開Unicode
            AFXAPI MFC提供的函數(shù)
            CALLBACK 通過指針回調(diào)的函數(shù)
            庫標(biāo)識符命名法 標(biāo)識符 值和含義
            u ANSI(N)或Unicode(U)
            d 調(diào)試或發(fā)行:D = 調(diào)試;忽略標(biāo)識符為發(fā)行。
            靜態(tài)庫版本命名規(guī)范 庫 描述
            NAFXCWD.LIB 調(diào)試版本:MFC靜態(tài)連接庫
            NAFXCW.LIB 發(fā)行版本:MFC靜態(tài)連接庫
            UAFXCWD.LIB 調(diào)試版本:具有Unicode支持的MFC靜態(tài)連接庫
            UAFXCW.LIB 發(fā)行版本:具有Unicode支持的MFC靜態(tài)連接庫
            動態(tài)連接庫命名規(guī)范 名稱 類型
            _AFXDLL 唯一的動態(tài)連接庫(DLL)版本
            WINAPI Windows所提供的函數(shù)
            Windows.h中新的命名規(guī)范 類型 定義描述
            WINAPI 使用在API聲明中的FAR PASCAL位置,如果正在編寫一個(gè)具有導(dǎo)出API人口點(diǎn)的DLL,則可以在自己的API中使用該類型
            CALLBACK 使用在應(yīng)用程序回叫例程,如窗口和對話框過程中的FAR PASCAL的位置
            LPCSTR 與LPSTR相同,只是LPCSTR用于只讀串指針,其定義類似(const char FAR*)
            UINT 可移植的無符號整型類型,其大小由主機(jī)環(huán)境決定(對于Windows NT和Windows 9x為32位);它是unsigned int的同義詞
            LRESULT 窗口程序返回值的類型
            LPARAM 聲明lParam所使用的類型,lParam是窗口程序的第四個(gè)參數(shù)
            WPARAM 聲明wParam所使用的類型,wParam是窗口程序的第三個(gè)參數(shù)
            LPVOID 一般指針類型,與(void *)相同,可以用來代替LPSTR
            --------------------------------------------------------------------------------
            抨擊匈牙利命名法
            匈牙利命名法是一種編程時(shí)的命名規(guī)范。命名規(guī)范是程序書寫規(guī)范中最重要也是最富爭議的地方,自 古乃兵家必爭之地。命名規(guī)范有何用?四個(gè)字:名正言順。用二分法,命名規(guī)范分為好的命名規(guī)范和壞的命名規(guī)范,也就是說名正言順的命名規(guī)范和名不正言不順的 命名規(guī)范。好的舞鞋是讓舞者感覺不到其存在的舞鞋,壞的舞鞋是讓舞者帶著鐐銬起舞。一個(gè)壞的命名規(guī)范具有的破壞力比一個(gè)好的命名規(guī)范具有的創(chuàng)造力要大得 多。
            本文要證明的是:匈牙利命名法是一個(gè)壞的命名規(guī)范。本文的作用范圍為靜態(tài)強(qiáng)類型編程語言。本文的分析范本為C語言和C++語言。下文中的匈法為匈牙利命名法的簡稱。
            一 匈牙利命名法的成本
            匈法的表現(xiàn)形式為給變量名附加上類型名前綴,例 如:nFoo,szFoo,pFoo,cpFoo分別表示整型變量,字符串型變量,指針型變量和常指針型變量。可以看出,匈法將變量的類型信息從單一地點(diǎn) (聲明變量處)復(fù)制到了多個(gè)地點(diǎn)(使用變量處),這是冗余法。冗余法的成本之一是要維護(hù)副本的一致性。這個(gè)成本在編寫和維護(hù)代碼的過程中需要改變變量的類 型時(shí)付出。冗余法的成本之二是占用了額外的空間。一個(gè)優(yōu)秀的書寫者會自覺地遵從一個(gè)法則:代碼最小組織單位的長度以30個(gè)自然行以下為宜,如果超過50行 就應(yīng)該重新組織。一個(gè)變量的書寫空間會給這一法則添加不必要的難度。
            二 匈牙利命名法的收益
            這里要證明匈牙利命名法的收益是含糊的,無法預(yù)期的。
            范本1:strcpy(pstrFoo,pcstrFoo2) Vs strcpy(foo,foo2)
            匈法在這里有什么收益呢?我看不到。沒有一個(gè)程序員會承認(rèn)自己不知道strcpy函數(shù)的參數(shù)類型吧。
            范本2:unknown_function(nFoo) Vs unknown_function(foo)
            匈法在這里有什么收益呢?我看不到。對于一個(gè)不知道確定類型的函數(shù),程序員應(yīng)該去查看該函數(shù)的 文檔,這是一種成本。使用匈法的唯一好處是看代碼的人知道這個(gè)函數(shù)要求一個(gè)整型參數(shù),這又有什么用處呢?函數(shù)是一種接口,參數(shù)的類型僅僅是接口中的一小部 分。諸如函數(shù)的功能、出口信息、線程安全性、異常安全性、參數(shù)合法性等重要信息還是必須查閱文檔。
            范本3:nFoo=nBar Vs foo=bar
            匈法在這里有什么收益呢?我看不到。使用匈法的唯一好處是看代碼的人知道這里發(fā)生了一個(gè)整型變 量的復(fù)制動作,聽起來沒什么問題,可以安心睡大覺了。如果他看到的是nFoo=szBar,可能會從美夢中驚醒。且慢,事情真的會是這樣嗎?我想首先被驚 醒的應(yīng)該是編譯器。另一方面,nFoo=nBar只是在語法上合法而已,看代碼的人真正關(guān)心的是語義的合法性,匈法對此毫無幫助。另一方面,一個(gè)優(yōu)秀的書 寫者會自覺地遵從一個(gè)法則:代碼最小組織單位中的臨時(shí)變量以一兩個(gè)為宜,如果超過三個(gè)就應(yīng)該重新組織。結(jié)合前述第一個(gè)法則,可以得出這樣的結(jié)論:易于理解 的代碼本身就應(yīng)該是易于理解的,這是代碼的內(nèi)建高質(zhì)量。好的命名規(guī)范對內(nèi)建高質(zhì)量的助益相當(dāng)有限,而壞的命名規(guī)范對內(nèi)建高質(zhì)量的損害比人們想象的要大。
            三 匈牙利命名法的實(shí)施
            這里要證明匈牙利命名法在C語言是難以實(shí)施的,在C++語言中是無法實(shí)施的。從邏輯上講,對匈法的收益做出否定的結(jié)論以后,再來論證匈法的可行性,是畫蛇添足。不過有鑒于小馬哥曾讓已射殺之?dāng)乘阑覐?fù)燃,我還是再踏上一支腳為妙。
            前面講過,匈法是類型系統(tǒng)的冗余,所以實(shí)施匈法的關(guān)鍵是我們是否能夠精確地對類型系統(tǒng)進(jìn)行復(fù)制。這取決于類型系統(tǒng)的復(fù)雜性。
            先來看看C語言:
            1.內(nèi)置類型:int,char,float,double 復(fù)制為 n,ch,f,d?好像沒有什么問題。不過誰來告訴我void應(yīng)該怎么表示?
            2.組合類型:array,union,enum,struct 復(fù)制為 a,u,e,s?好像比較別扭。
            這里的難點(diǎn)不是為主類型取名,而是為副類型取名。an表示整型數(shù)組?sfoo,sbar表示結(jié)構(gòu)foo,結(jié)構(gòu)bar?ausfoo表示聯(lián)合結(jié)構(gòu)foo數(shù)組?累不累啊。
            3.特殊類型:pointer。pointer在理論上應(yīng)該是組合類型,但是在C語言中可以認(rèn)為是內(nèi)置類型,因?yàn)镃語言并沒有非常嚴(yán)格地區(qū)分不同的指針類型。下面開始表演:pausfoo表示聯(lián)合結(jié)構(gòu)foo數(shù)組指針?ppp表示指針的指針的指針?
            噩夢還沒有結(jié)束,再來看看類型系統(tǒng)更阿為豐富的C++語言:
            1.class:如果說C語言中的struct還可以用stru搪塞過去的話,不要夢想用 cls來搪塞C++中的class。嚴(yán)格地講,class根本就并不是一個(gè)類型,而是創(chuàng)造類型的工具,在C++中,語言內(nèi)置類型的數(shù)量和class創(chuàng)造的 用戶自定義類型的數(shù)量相比完全可以忽略不計(jì)。stdvectorFoo表示標(biāo)準(zhǔn)庫向量類型變量Foo?瘋狂的念頭。
            2.命名空間:boostfilesystemiteratorFoo,表示boost空間filesystem子空間遍歷目錄類型變量Foo?程序員要崩潰了。
            3.模板:你記得std::map<std::string,std::string>類型的確切名字嗎?我是記不得了,好像超過255個(gè)字符,還是饒了我吧。
            4.模板參數(shù):template <class T, class BinaryPredicate>const T& max(const T& a, const T& b, BinaryPredicate comp) 聰明的你,請用匈法為T命名。上帝在發(fā)笑。
            5.類型修飾:static,extern,mutable,register,volatile,const,short,long,unsigned 噩夢加上修飾是什么?還是噩夢。

          文章來源:http://blog.163.com/ccbobo_cat/blog/static/32099462200931411226261
          posted @ 2009-04-14 23:02 C.B.K 閱讀(96) | 評論 (0)編輯 收藏
          僅列出標(biāo)題
          共2頁: 上一頁 1 2 
          主站蜘蛛池模板: 瓦房店市| 西宁市| 阆中市| 昌吉市| 科技| 安仁县| 伊春市| 通许县| 罗城| 洞头县| 蓬莱市| 汶上县| 德钦县| 兴业县| 红原县| 浏阳市| 梧州市| 宜昌市| 荔浦县| 浦江县| 如东县| 靖州| 墨脱县| 江永县| 博客| 邵阳县| 邯郸县| 天全县| 循化| 崇礼县| 鄱阳县| 景宁| 项城市| 锦屏县| 汾阳市| 肥西县| 永丰县| 马鞍山市| 那曲县| 彰化市| 望奎县|