我的Blog我做主^_^

          走向一條通往JAVA的不歸路...

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            64 隨筆 :: 68 文章 :: 77 評(píng)論 :: 0 Trackbacks

          2007年4月22日 #

          org.apache.jasper.JasperException: Failed to load or instantiate TagLibraryValidator class: org.apache.taglibs.standard.tlv.JstlCoreTLV

          原因是缺少.jar文件

          至于是缺少standard.jar還是servlet-api.jar還是兩個(gè)都缺那就看你引了哪個(gè)了

          posted @ 2011-05-18 11:45 java_蟈蟈 閱讀(2991) | 評(píng)論 (0)編輯 收藏

          JDK1.5中,String類新增了一個(gè)很有用的靜態(tài)方法String.format():
          format(Locale l, String format, Object... args) 使用指定的語(yǔ)言環(huán)境、格式字符串和參數(shù)返回一個(gè)格式化字符串。
          format(String format, Object... args) 使用指定的格式字符串和參數(shù)返回一個(gè)格式化字符串。

          舉幾個(gè)這個(gè)方法實(shí)用的例子(注釋是輸出結(jié)果):

          CODE:

          long now = System.currentTimeMillis();

          String s = String.format("%tR", now);   // "15:12"

          CODE:

          // Current month/day/year

          Date d = new Date(now);

          s = String.format("%tD", d);                // "07/13/04"

          CODE:

          s = String.format("%,d", Integer.MAX_VALUE); // "2,147,483,647"

          CODE:

          s = String.format("%05d", 123);              // "00123"
          是不是很方便,讓人動(dòng)心啊?哈哈,還有更多的效果!

          其實(shí)format函數(shù)有些類似c語(yǔ)言中printf函數(shù),一些格式字符串與 C 類似,但已進(jìn)行了某些定制,以適應(yīng) Java 語(yǔ)言,并且利用了其中一些特性。此方法提供了對(duì)布局對(duì)齊和排列的支持,以及對(duì)數(shù)值、字符串和日期/時(shí)間數(shù)據(jù)的常規(guī)格式和特定于語(yǔ)言環(huán)境的輸出的支持。支持諸如 byte、BigDecimal 和 Calendar 等常見 Java 類型。

          產(chǎn)生格式化輸出的每個(gè)方法都需要格式字符串 和參數(shù)列表。格式字符串是一個(gè) String,它可以包含固定文本以及一個(gè)或多個(gè)嵌入的格式說(shuō)明符。請(qǐng)考慮以下示例:

          Calendar c = ...;
          String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);

          格式字符串是 format 方法的第一個(gè)參數(shù)。它包含三個(gè)格式說(shuō)明符 "%1$tm"、"%1$te" 和 "%1$tY",它們指出應(yīng)該如何處理參數(shù)以及在文本的什么地方插入它們。格式字符串的其余部分是包括 "Dukes Birthday: " 和其他任何空格或標(biāo)點(diǎn)符號(hào)的固定文本。 參數(shù)列表由傳遞給位于格式字符串之后的方法的所有參數(shù)組成。在上述示例中,參數(shù)列表的大小為 1,由新對(duì)象 Calendar 組成。

          1.常規(guī)類型、字符類型和數(shù)值類型的格式說(shuō)明符的語(yǔ)法如下:%[argument_index$][flags][width][.precision]conversion

          可選的 argument_index 是一個(gè)十進(jìn)制整數(shù),用于表明參數(shù)在參數(shù)列表中的位置。第一個(gè)參數(shù)由 "1$" 引用,第二個(gè)參數(shù)由 "2$" 引用,依此類推。
          可選的 flags 是修改輸出格式的字符集。有效標(biāo)志的集合取決于轉(zhuǎn)換類型。
          可選 width 是一個(gè)非負(fù)十進(jìn)制整數(shù),表明要向輸出中寫入的最少字符數(shù)。
          可選 precision 是一個(gè)非負(fù)十進(jìn)制整數(shù),通常用來(lái)限制字符數(shù)。特定行為取決于轉(zhuǎn)換類型。
          所需的 conversion 是一個(gè)表明應(yīng)該如何格式化參數(shù)的字符。給定參數(shù)的有效轉(zhuǎn)換集合取決于參數(shù)的數(shù)據(jù)類型。

          2.用來(lái)表示日期和時(shí)間類型的格式說(shuō)明符的語(yǔ)法如下:
          %[argument_index$][flags][width]conversion

          可選的 argument_index、flags 和 width 的定義同上。
          所需的 conversion 是一個(gè)由兩字符組成的序列。第一個(gè)字符是 't' 或 'T'。第二個(gè)字符表明所使用的格式。這些字符類似于但不完全等同于那些由 GNU date 和 POSIX strftime(3c) 定義的字符。


          3.與參數(shù)不對(duì)應(yīng)的格式說(shuō)明符的語(yǔ)法如下:
          %[flags][width]conversion

          可選 flags 和 width 的定義同上。
          所需的 conversion 是一個(gè)表明要在輸出中所插內(nèi)容的字符。

          轉(zhuǎn)換
          轉(zhuǎn)換可分為以下幾類:
          1. 常規(guī) - 可應(yīng)用于任何參數(shù)類型
          2. 字符 - 可應(yīng)用于表示 Unicode 字符的基本類型:char、Character、byte、Byte、short 和 Short。當(dāng) Character.isValidCodePoint(int) 返回 true 時(shí),可將此轉(zhuǎn)換應(yīng)用于 int 和 Integer 類型
          3. 數(shù)值
                1. 整數(shù) - 可應(yīng)用于 Java 的整數(shù)類型:byte、Byte、short、Short、int、Integer、long、Long 和 BigInteger
                2. 浮點(diǎn) - 可用于 Java 的浮點(diǎn)類型:float、Float、double、Double 和 BigDecimal
          4. 日期/時(shí)間 - 可應(yīng)用于 Java 的、能夠?qū)θ掌诨驎r(shí)間進(jìn)行編碼的類型:long、Long、Calendar 和 Date。
          5. 百分比 - 產(chǎn)生字面值 '%' ('\u0025')
          6. 行分隔符 - 產(chǎn)生特定于平臺(tái)的行分隔符

          下表總結(jié)了受支持的轉(zhuǎn)換。由大寫字符(如 'B'、'H'、'S'、'C'、'X'、'E'、'G'、'A' 和 'T')表示的轉(zhuǎn)換與由相應(yīng)的小寫字符的轉(zhuǎn)換等同,根據(jù)流行的 Locale 規(guī)則將結(jié)果轉(zhuǎn)換為大寫形式除外。后者等同于 String.toUpperCase() 的以下調(diào)用.

           

          轉(zhuǎn)換 參數(shù)類別 說(shuō)明
          'b', 'B' 常規(guī) 如果參數(shù) arg 為 null,則結(jié)果為 "false"。如果 arg 是一個(gè) boolean 值或 Boolean,則結(jié)果為 String.valueOf() 返回的字符串。否則結(jié)果為 "true"。
          'h', 'H' 常規(guī) 如果參數(shù) arg 為 null,則結(jié)果為 "null"。否則,結(jié)果為調(diào)用 Integer.toHexString(arg.hashCode()) 得到的結(jié)果。
          's', 'S' 常規(guī) 如果參數(shù) arg 為 null,則結(jié)果為 "null"。如果 arg 實(shí)現(xiàn) Formattable,則調(diào)用 arg.formatTo。否則,結(jié)果為調(diào)用 arg.toString() 得到的結(jié)果。
          'c', 'C' 字符 結(jié)果是一個(gè) Unicode 字符
          'd' 整數(shù) 結(jié)果被格式化為十進(jìn)制整數(shù)
          'o' 整數(shù) 結(jié)果被格式化為八進(jìn)制整數(shù)
          'x', 'X' 整數(shù) 結(jié)果被格式化為十六進(jìn)制整數(shù)
          'e', 'E' 浮點(diǎn) 結(jié)果被格式化為用計(jì)算機(jī)科學(xué)記數(shù)法表示的十進(jìn)制數(shù)
          'f' 浮點(diǎn) 結(jié)果被格式化為十進(jìn)制數(shù)
          'g', 'G' 浮點(diǎn) 根據(jù)精度和舍入運(yùn)算后的值,使用計(jì)算機(jī)科學(xué)記數(shù)形式或十進(jìn)制格式對(duì)結(jié)果進(jìn)行格式化。
          'a', 'A' 浮點(diǎn) 結(jié)果被格式化為帶有效位數(shù)和指數(shù)的十六進(jìn)制浮點(diǎn)數(shù)
          't', 'T' 日期/時(shí)間 日期和時(shí)間轉(zhuǎn)換字符的前綴。請(qǐng)參閱日期/時(shí)間轉(zhuǎn)換。
          '%' 百分比 結(jié)果為字面值 '%' ('\u0025')
          'n' 行分隔符 結(jié)果為特定于平臺(tái)的行分隔符

          任何未明確定義為轉(zhuǎn)換的字符都是非法字符,并且都被保留,以供將來(lái)擴(kuò)展使用。

          日期/時(shí)間轉(zhuǎn)換
          以下日期和時(shí)間轉(zhuǎn)換的后綴字符是為 't' 和 'T' 轉(zhuǎn)換定義的。這些類型相似于但不完全等同于那些由 GNU date 和 POSIX strftime(3c) 定義的類型。提供其他轉(zhuǎn)換類型是為了訪問(wèn)特定于 Java 的功能(如將 'L' 用作秒中的毫秒)。

          以下轉(zhuǎn)換字符用來(lái)格式化時(shí)間:

          'H' 24 小時(shí)制的小時(shí),被格式化為必要時(shí)帶前導(dǎo)零的兩位數(shù),即 00 - 23。
          'I' 12 小時(shí)制的小時(shí),被格式化為必要時(shí)帶前導(dǎo)零的兩位數(shù),即 01 - 12。
          'k' 24 小時(shí)制的小時(shí),即 0 - 23。
          'l' 12 小時(shí)制的小時(shí),即 1 - 12。
          'M' 小時(shí)中的分鐘,被格式化為必要時(shí)帶前導(dǎo)零的兩位數(shù),即 00 - 59。
          'S' 分鐘中的秒,被格式化為必要時(shí)帶前導(dǎo)零的兩位數(shù),即 00 - 60 ("60" 是支持閏秒所需的一個(gè)特殊值)。
          'L' 秒中的毫秒,被格式化為必要時(shí)帶前導(dǎo)零的三位數(shù),即 000 - 999。
          'N' 秒中的毫微秒,被格式化為必要時(shí)帶前導(dǎo)零的九位數(shù),即 000000000 - 999999999。
          'p' 特定于語(yǔ)言環(huán)境的 上午或下午 標(biāo)記以小寫形式表示,例如 "am" 或 "pm"。使用轉(zhuǎn)換前綴 'T' 可以強(qiáng)行將此輸出轉(zhuǎn)換為大寫形式。
          'z' 相對(duì)于 GMT 的 RFC 822 格式的數(shù)字時(shí)區(qū)偏移量,例如 -0800。
          'Z' 表示時(shí)區(qū)縮寫形式的字符串。Formatter 的語(yǔ)言環(huán)境將取代參數(shù)的語(yǔ)言環(huán)境(如果有)。
          's' 自協(xié)調(diào)世界時(shí) (UTC) 1970 年 1 月 1 日 00:00:00 至現(xiàn)在所經(jīng)過(guò)的秒數(shù),即 Long.MIN_VALUE/1000 與 Long.MAX_VALUE/1000 之間的差值。
          'Q' 自協(xié)調(diào)世界時(shí) (UTC) 1970 年 1 月 1 日 00:00:00 至現(xiàn)在所經(jīng)過(guò)的毫秒數(shù),即 Long.MIN_VALUE 與 Long.MAX_VALUE 之間的差值。

          以下轉(zhuǎn)換字符用來(lái)格式化日期:

          'B' 特定于語(yǔ)言環(huán)境的月份全稱,例如 "January" 和 "February"。
          'b' 特定于語(yǔ)言環(huán)境的月份簡(jiǎn)稱,例如 "Jan" 和 "Feb"。
          'h' 與 'b' 相同。
          'A' 特定于語(yǔ)言環(huán)境的星期幾全稱,例如 "Sunday" 和 "Monday"
          'a' 特定于語(yǔ)言環(huán)境的星期幾簡(jiǎn)稱,例如 "Sun" 和 "Mon"
          'C' 除以 100 的四位數(shù)表示的年份,被格式化為必要時(shí)帶前導(dǎo)零的兩位數(shù),即 00 - 99
          'Y' 年份,被格式化為必要時(shí)帶前導(dǎo)零的四位數(shù)(至少),例如,0092 等于格里高利歷的 92 CE。
          'y' 年份的最后兩位數(shù),被格式化為必要時(shí)帶前導(dǎo)零的兩位數(shù),即 00 - 99。
          'j' 一年中的天數(shù),被格式化為必要時(shí)帶前導(dǎo)零的三位數(shù),例如,對(duì)于格里高利歷是 001 - 366。
          'm' 月份,被格式化為必要時(shí)帶前導(dǎo)零的兩位數(shù),即 01 - 13。
          'd' 一個(gè)月中的天數(shù),被格式化為必要時(shí)帶前導(dǎo)零兩位數(shù),即 01 - 31
          'e' 一個(gè)月中的天數(shù),被格式化為兩位數(shù),即 1 - 31。

          以下轉(zhuǎn)換字符用于格式化常見的日期/時(shí)間組合。

          'R' 24 小時(shí)制的時(shí)間,被格式化為 "%tH:%tM"
          'T' 24 小時(shí)制的時(shí)間,被格式化為 "%tH:%tM:%tS"。
          'r' 12 小時(shí)制的時(shí)間,被格式化為 "%tI:%tM:%tS %Tp"。上午或下午標(biāo)記 ('%Tp') 的位置可能與語(yǔ)言環(huán)境有關(guān)。
          'D' 日期,被格式化為 "%tm/%td/%ty"。
          'F' ISO 8601 格式的完整日期,被格式化為 "%tY-%tm-%td"。
          'c' 日期和時(shí)間,被格式化為 "%ta %tb %td %tT %tZ %tY",例如 "Sun Jul 20 16:17:00 EDT 1969"。

          任何未明確定義為轉(zhuǎn)換的字符都是非法字符,并且都被保留,以供將來(lái)擴(kuò)展使用。


          標(biāo)志
          下表總結(jié)了受支持的標(biāo)志。y 表示該標(biāo)志受指示參數(shù)類型支持。

          標(biāo)志 常規(guī) 字符 整數(shù) 浮點(diǎn) 日期/時(shí)間 說(shuō)明
          '-' y     y     y     y     y 結(jié)果將是左對(duì)齊的。
          '#' y1     -     y3     y     -     結(jié)果應(yīng)該使用依賴于轉(zhuǎn)換類型的替換形式
          '+' -     -     y4     y     -     結(jié)果總是包括一個(gè)符號(hào)
          '   ' -     -     y4     y     -     對(duì)于正值,結(jié)果中將包括一個(gè)前導(dǎo)空格
          '0' -     -     y     y     -     結(jié)果將用零來(lái)填充
          ',' -     -     y2     y5     -     結(jié)果將包括特定于語(yǔ)言環(huán)境的組分隔符
          '(' -     -     y4     y5     -     結(jié)果將是用圓括號(hào)括起來(lái)的負(fù)數(shù)

          1 取決于 Formattable 的定義。

          2 只適用于 'd' 轉(zhuǎn)換。

          3 只適用于 'o'、'x' 和 'X' 轉(zhuǎn)換。

          4 對(duì) BigInteger 應(yīng)用 'd'、'o'、'x' 和 'X' 轉(zhuǎn)換時(shí),或者對(duì) byte 及 Byte、short 及 Short、int 及 Integer、long 及 Long 分別應(yīng)用 'd' 轉(zhuǎn)換時(shí)適用。

          5 只適用于 'e'、'E'、'f'、'g' 和 'G' 轉(zhuǎn)換。

          任何未顯式定義為標(biāo)志的字符都是非法字符,并且都被保留,以供擴(kuò)展使用。

          寬度   寬度是將向輸出中寫入的最少字符數(shù)。對(duì)于行分隔符轉(zhuǎn)換,不適用寬度,如果提供寬度,則會(huì)拋出異常。
          精度   對(duì)于常規(guī)參數(shù)類型,精度是將向輸出中寫入的最多字符數(shù)。
          對(duì)于浮點(diǎn)轉(zhuǎn)換 'e'、'E' 和 'f',精度是小數(shù)點(diǎn)分隔符后的位數(shù)。如果轉(zhuǎn)換是 'g' 或 'G',那么精度是舍入計(jì)算后所得數(shù)值的所有位數(shù)。如果轉(zhuǎn)換是 'a' 或 'A',則不必指定精度。
          對(duì)于字符、整數(shù)和日期/時(shí)間參數(shù)類型轉(zhuǎn)換,以及百分比和行分隔符轉(zhuǎn)換,精度是不適用的;如果提供精度,則會(huì)拋出異常。
          參數(shù)索引   參數(shù)索引是一個(gè)十進(jìn)制整數(shù),用于表明參數(shù)在參數(shù)列表中的位置。第一個(gè)參數(shù)由 "1$" 引用,第二個(gè)參數(shù)由 "2$" 引用,依此類推。
          根據(jù)位置引用參數(shù)的另一種方法是使用 '<' ('\u003c') 標(biāo)志,這將會(huì)重用以前格式說(shuō)明符的參數(shù)。例如,以下兩條語(yǔ)句產(chǎn)生的字符相同:
           

          Calendar c = ...;
          String s1 = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);

          String s2 = String.format("Duke's Birthday: %1$tm %<$te,%<$tY", c);

           


          在JDK1.5中,String類增加了一個(gè)非常有用的靜態(tài)函數(shù)format(String  format, Objece...  argues),可以將各類數(shù)據(jù)格式化為字符串并輸出。其中format參數(shù)指定了輸出的格式,是最復(fù)雜也是最難掌握的一點(diǎn),而argues則是一系列等待被格式化的對(duì)象。該函數(shù)對(duì)c語(yǔ)言中printf函數(shù)的用法進(jìn)行了一定的模仿,因此有c語(yǔ)言基礎(chǔ)的人學(xué)起來(lái)會(huì)輕松許多。下面我們著重討論一下format 參數(shù)的格式及含義。
                  format參數(shù)中可以包含不需要轉(zhuǎn)化的字符串,這些字符串是你寫什么,最終就輸出什么。同時(shí)還包含一些特殊格式的內(nèi)容,來(lái)指定將哪個(gè)對(duì)象來(lái)轉(zhuǎn)換,以及轉(zhuǎn)換成什么形式。這種特殊的格式通通以%index$開頭,index從1開始取值,表示將第index個(gè)參數(shù)拿進(jìn)來(lái)進(jìn)行格式化。這一點(diǎn)比c語(yǔ)言要強(qiáng)一點(diǎn), c語(yǔ)言只能按照參數(shù)的順序依次格式化,而java可以選擇第n個(gè)參數(shù)來(lái)格式化。由于該函數(shù)可以對(duì)任意一個(gè)對(duì)象進(jìn)行格式化,不同的對(duì)象適用的參數(shù)也不同,因此我們下面分類來(lái)討論。

          1.對(duì)整數(shù)進(jìn)行格式化:%[index$][標(biāo)識(shí)][最小寬度]轉(zhuǎn)換方式
                  我們可以看到,格式化字符串由4部分組成,其中%[index$]的含義我們上面已經(jīng)講過(guò),[最小寬度]的含義也很好理解,就是最終該整數(shù)轉(zhuǎn)化的字符串最少包含多少位數(shù)字。我們來(lái)看看剩下2個(gè)部分的含義吧:

           


          標(biāo)識(shí):
          '-'    在最小寬度內(nèi)左對(duì)齊,不可以與“用0填充”同時(shí)使用
          '#'    只適用于8進(jìn)制和16進(jìn)制,8進(jìn)制時(shí)在結(jié)果前面增加一個(gè)0,16進(jìn)制時(shí)在結(jié)果前面增加0x
          '+'    結(jié)果總是包括一個(gè)符號(hào)(一般情況下只適用于10進(jìn)制,若對(duì)象為BigInteger才可以用于8進(jìn)制和16進(jìn)制)
          '  '    正值前加空格,負(fù)值前加負(fù)號(hào)(一般情況下只適用于10進(jìn)制,若對(duì)象為BigInteger才可以用于8進(jìn)制和16進(jìn)制)
          '0'    結(jié)果將用零來(lái)填充
          ','    只適用于10進(jìn)制,每3位數(shù)字之間用“,”分隔
          '('    若參數(shù)是負(fù)數(shù),則結(jié)果中不添加負(fù)號(hào)而是用圓括號(hào)把數(shù)字括起來(lái)(同‘+’具有同樣的限制)

          轉(zhuǎn)換方式:
          d-十進(jìn)制   o-八進(jìn)制   x或X-十六進(jìn)制        上面的說(shuō)明過(guò)于枯燥,我們來(lái)看幾個(gè)具體的例子。需要特別注意的一點(diǎn)是:大部分標(biāo)識(shí)字符可以同時(shí)使用。

                  System.out.println(String.format("%1$,09d", -3123));
                  System.out.println(String.format("%1$9d", -31));
                  System.out.println(String.format("%1$-9d", -31));
                  System.out.println(String.format("%1$(9d", -31));
                  System.out.println(String.format("%1$#9x", 5689));

          //結(jié)果為:
          //-0003,123
          //      -31
          //-31     
          //     (31)
          //   0x1639

          2.對(duì)浮點(diǎn)數(shù)進(jìn)行格式化:%[index$][標(biāo)識(shí)][最少寬度][.精度]轉(zhuǎn)換方式
                  我們可以看到,浮點(diǎn)數(shù)的轉(zhuǎn)換多了一個(gè)“精度”選項(xiàng),可以控制小數(shù)點(diǎn)后面的位數(shù)。

          標(biāo)識(shí):
          '-'    在最小寬度內(nèi)左對(duì)齊,不可以與“用0填充”同時(shí)使用
          '+'    結(jié)果總是包括一個(gè)符號(hào)
          '  '    正值前加空格,負(fù)值前加負(fù)號(hào)
          '0'    結(jié)果將用零來(lái)填充
          ','    每3位數(shù)字之間用“,”分隔(只適用于fgG的轉(zhuǎn)換)
          '('    若參數(shù)是負(fù)數(shù),則結(jié)果中不添加負(fù)號(hào)而是用圓括號(hào)把數(shù)字括起來(lái)(只適用于eEfgG的轉(zhuǎn)換)

          轉(zhuǎn)換方式:
          'e', 'E'  --  結(jié)果被格式化為用計(jì)算機(jī)科學(xué)記數(shù)法表示的十進(jìn)制數(shù)
          'f'          --  結(jié)果被格式化為十進(jìn)制普通表示方式
          'g', 'G'    --  根據(jù)具體情況,自動(dòng)選擇用普通表示方式還是科學(xué)計(jì)數(shù)法方式
          'a', 'A'    --   結(jié)果被格式化為帶有效位數(shù)和指數(shù)的十六進(jìn)制浮點(diǎn)數(shù)

          3.對(duì)字符進(jìn)行格式化:
                  對(duì)字符進(jìn)行格式化是非常簡(jiǎn)單的,c表示字符,標(biāo)識(shí)中'-'表示左對(duì)齊,其他就沒(méi)什么了。

          4.對(duì)百分比符號(hào)進(jìn)行格式化:
                  看了上面的說(shuō)明,大家會(huì)發(fā)現(xiàn)百分比符號(hào)“%”是特殊格式的一個(gè)前綴。那么我們要輸入一個(gè)百分比符號(hào)該怎么辦呢?肯定是需要轉(zhuǎn)義字符的,但是要注意的是,在這里轉(zhuǎn)義字符不是“\”,而是“%”。換句話說(shuō),下面這條語(yǔ)句可以輸出一個(gè)“12%”:
          System.out.println(String.format("%1$d%%", 12));

          5.取得平臺(tái)獨(dú)立的行分隔符:
                  System.getProperty("line.separator")可以取得平臺(tái)獨(dú)立的行分隔符,但是用在format中間未免顯得過(guò)于煩瑣了。于是format函數(shù)自帶了一個(gè)平臺(tái)獨(dú)立的行分隔符那就是String.format("%n")。

          6.對(duì)日期類型進(jìn)行格式化:
                   以下日期和時(shí)間轉(zhuǎn)換的后綴字符是為 't' 和 'T' 轉(zhuǎn)換定義的。這些類型相似于但不完全等同于那些由 GNU date 和 POSIX strftime(3c) 定義的類型。提供其他轉(zhuǎn)換類型是為了訪問(wèn)特定于 Java 的功能(如將 'L' 用作秒中的毫秒)。

          以下轉(zhuǎn)換字符用來(lái)格式化時(shí)間:
          'H'     24 小時(shí)制的小時(shí),被格式化為必要時(shí)帶前導(dǎo)零的兩位數(shù),即 00 - 23。
          'I'     12 小時(shí)制的小時(shí),被格式化為必要時(shí)帶前導(dǎo)零的兩位數(shù),即 01 - 12。
          'k'     24 小時(shí)制的小時(shí),即 0 - 23。
          'l'     12 小時(shí)制的小時(shí),即 1 - 12。
          'M'     小時(shí)中的分鐘,被格式化為必要時(shí)帶前導(dǎo)零的兩位數(shù),即 00 - 59。
          'S'     分鐘中的秒,被格式化為必要時(shí)帶前導(dǎo)零的兩位數(shù),即 00 - 60 ("60" 是支持閏秒所需的一個(gè)特殊值)。
          'L'     秒中的毫秒,被格式化為必要時(shí)帶前導(dǎo)零的三位數(shù),即 000 - 999。
          'N'     秒中的毫微秒,被格式化為必要時(shí)帶前導(dǎo)零的九位數(shù),即 000000000 - 999999999。
          'p'     特定于語(yǔ)言環(huán)境的上午或下午 標(biāo)記以小寫形式表示,例如 "am" 或 "pm"。使用轉(zhuǎn)換前綴 'T' 可以強(qiáng)行將此輸出轉(zhuǎn)換為大寫形式。
          'z'     相對(duì)于 GMT 的 RFC 822 格式的數(shù)字時(shí)區(qū)偏移量,例如 -0800。
          'Z'     表示時(shí)區(qū)縮寫形式的字符串。Formatter 的語(yǔ)言環(huán)境將取代參數(shù)的語(yǔ)言環(huán)境(如果有)。
          's'     自協(xié)調(diào)世界時(shí) (UTC) 1970 年 1 月 1 日 00:00:00 至現(xiàn)在所經(jīng)過(guò)的秒數(shù),即 Long.MIN_VALUE/1000 與 Long.MAX_VALUE/1000 之間的差值。
          'Q'     自協(xié)調(diào)世界時(shí) (UTC) 1970 年 1 月 1 日 00:00:00 至現(xiàn)在所經(jīng)過(guò)的毫秒數(shù),即 Long.MIN_VALUE 與 Long.MAX_VALUE 之間的差值。

          以下轉(zhuǎn)換字符用來(lái)格式化日期:
          'B'     特定于語(yǔ)言環(huán)境的月份全稱,例如 "January" 和 "February"。
          'b'     特定于語(yǔ)言環(huán)境的月份簡(jiǎn)稱,例如 "Jan" 和 "Feb"。
          'h'     與 'b' 相同。
          'A'     特定于語(yǔ)言環(huán)境的星期幾全稱,例如 "Sunday" 和 "Monday"
          'a'     特定于語(yǔ)言環(huán)境的星期幾簡(jiǎn)稱,例如 "Sun" 和 "Mon"
          'C'     除以 100 的四位數(shù)表示的年份,被格式化為必要時(shí)帶前導(dǎo)零的兩位數(shù),即 00 - 99
          'Y'     年份,被格式化為必要時(shí)帶前導(dǎo)零的四位數(shù)(至少),例如,0092 等于格里高利歷的 92 CE。
          'y'     年份的最后兩位數(shù),被格式化為必要時(shí)帶前導(dǎo)零的兩位數(shù),即 00 - 99。
          'j'     一年中的天數(shù),被格式化為必要時(shí)帶前導(dǎo)零的三位數(shù),例如,對(duì)于格里高利歷是 001 - 366。
          'm'     月份,被格式化為必要時(shí)帶前導(dǎo)零的兩位數(shù),即 01 - 13。
          'd'     一個(gè)月中的天數(shù),被格式化為必要時(shí)帶前導(dǎo)零兩位數(shù),即 01 - 31
          'e'     一個(gè)月中的天數(shù),被格式化為兩位數(shù),即 1 - 31。

          以下轉(zhuǎn)換字符用于格式化常見的日期/時(shí)間組合。
          'R'     24 小時(shí)制的時(shí)間,被格式化為 "%tH:%tM"
          'T'     24 小時(shí)制的時(shí)間,被格式化為 "%tH:%tM:%tS"。
          'r'     12 小時(shí)制的時(shí)間,被格式化為 "%tI:%tM:%tS %Tp"。上午或下午標(biāo)記 ('%Tp') 的位置可能與語(yǔ)言環(huán)境有關(guān)。
          'D'     日期,被格式化為 "%tm/%td/%ty"。
          'F'     ISO 8601 格式的完整日期,被格式化為 "%tY-%tm-%td"。
          'c'     日期和時(shí)間,被格式化為 "%ta %tb %td %tT %tZ %tY",例如 "Sun Jul 20 16:17:00 EDT 1969"。
          文章出處:飛諾網(wǎng)(www.firnow.com):http://dev.firnow.com/course/3_program/java/javashl/2008107/148918.html

          posted @ 2011-05-17 08:22 java_蟈蟈 閱讀(2706) | 評(píng)論 (0)編輯 收藏

          當(dāng)start虛擬器的時(shí)候,之后就彈出:SDL_app:emulator.exe 應(yīng)用程序錯(cuò)誤
          在網(wǎng)上查了些資料,先刪除AVD`,然后重新創(chuàng)建新的AVD,再重新運(yùn)行項(xiàng)目竟然OK了,但關(guān)閉以后重新運(yùn)行又報(bào)相同的錯(cuò)誤。又在網(wǎng)上查了資料,查看任務(wù)管理器進(jìn)程中應(yīng)用是否還在運(yùn)行,但刪除停止應(yīng)用以后重新運(yùn)行項(xiàng)目還是報(bào)相同的錯(cuò)誤!
          解決方法:SD card size 不要設(shè)置,保準(zhǔn)可以。(大家可以試試,我不敢保證可行)。

          新建一個(gè)AVD以后,第一次跑起來(lái)OK的,關(guān)閉以后重新跑,又有問(wèn)題了,難道我每跑一次就重新建AVD?這個(gè)不是解決問(wèn)題的根本辦法...很多人說(shuō),SD card size 不要設(shè)置,可以避免這個(gè)問(wèn)題出現(xiàn)。


          本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/jincf2011/archive/2011/04/22/6342906.aspx

          posted @ 2011-05-03 15:44 java_蟈蟈 閱讀(2203) | 評(píng)論 (4)編輯 收藏

          Tomcat部署時(shí)報(bào)錯(cuò)Could not copy all resources to...

          轉(zhuǎn)自:http://jiake0504.iteye.com/blog/253604

          在使用eclipse開發(fā),發(fā)布應(yīng)用的時(shí)候突然無(wú)法成功發(fā)布,提示  
           
          Deployment failure on Tomcat  6.x. Could not copy all resources to D:\...\webapps\eptInfo. If a file is locked, you can wait until the lock times out to redeploy, or stop the server and redeploy, or manually remove the deployment at D:\....\webapps\eptInfo.  
           
          但是我的tomcat服務(wù)并沒(méi)有啟動(dòng).上網(wǎng)搜索之后發(fā)現(xiàn)和大家范的是一個(gè)毛病,原來(lái)工程中我引了一個(gè)包,后來(lái)這個(gè)包被我給刪除了,但是因?yàn)橐呀?jīng)發(fā)布過(guò)這個(gè)工程了,所以classpath中就有這個(gè)包名了,這樣發(fā)布的時(shí)候也會(huì)去找這個(gè)包但是已經(jīng)不存在了,所以無(wú)copy,  
           
          解決辦法:在eclipse的工程中點(diǎn)擊右健選擇properties-->java build path中已經(jīng)提示了xx.jar不存在,這樣就把這個(gè)jar信息從Libraries中刪除即可.  
           
          重新發(fā)布應(yīng)用,成功!
          posted @ 2011-05-03 11:27 java_蟈蟈 閱讀(2299) | 評(píng)論 (0)編輯 收藏

          刪除掉C:\Documents and Settings\hao\Application Data\Subversion\auth\svn.simple文件夾下的文件即可.
          posted @ 2010-12-14 11:51 java_蟈蟈 閱讀(321) | 評(píng)論 (0)編輯 收藏

               摘要: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>       <%@page import="com.rao.bean.Sex"%>    &nbs...  閱讀全文
          posted @ 2010-10-26 11:08 java_蟈蟈 閱讀(604) | 評(píng)論 (0)編輯 收藏

               摘要: 今天一個(gè)朋友問(wèn)起,將自己的想法寫出,以便備用

          EXEC sp_spaceused '表名'
          上面的語(yǔ)句查詢的是該表的數(shù)據(jù)大小及總行數(shù)
          下面的是執(zhí)行過(guò)程:
          一、將上述查詢出的總行數(shù)<@totalRow>及數(shù)據(jù)大小<@dataSize>放入臨時(shí)變量中
          二、將待分隔大小與總大小比較,看看要分成幾份,并將份數(shù)<@splitNum>記入臨時(shí)變量中
          三、執(zhí)行:select top @totalRow/@splitNum * into #temp from 表名 ; 并將@totalRow/@splitNum 的值放入@splitRows,并將開始行數(shù)<@startRow>及結(jié)尾行<@endRow>記錄
          四、執(zhí)行:EXEC sp_spaceused '#temp' 判斷其數(shù)據(jù)大小
          五、如果分隔出來(lái)的大小在合理范圍內(nèi),則執(zhí)行相同操作
          六、如果分隔出來(lái)的大小不在合理范圍內(nèi)則刪除臨時(shí)表,則重新執(zhí)行操作<三>   閱讀全文
          posted @ 2010-06-18 10:52 java_蟈蟈 閱讀(284) | 評(píng)論 (0)編輯 收藏

          本文引自:http://www.aygfsteel.com/176142998/archive/2009/02/03/221507.html

          Spring的JDBCTemplate

          當(dāng)hql等查詢方式不能滿足性能或靈活性的要求,必須使用SQL時(shí),大家有三種選擇:

          第一、使用Hibernate 的sql 查詢函數(shù),將查詢結(jié)果對(duì)象轉(zhuǎn)為Entity對(duì)象。

          第二、使用Hibernate Session的getConnection 獲得JDBC Connection,然后進(jìn)行純JDBC API操作;

          第三、選擇把Spring的JDBCTemplate作為一種很不錯(cuò)的JDBC Utils來(lái)使用。

               JDBCTemplate的使用很簡(jiǎn)單,只要在ApplicationContext文件里定義一個(gè)jdbcTemplate節(jié)點(diǎn),POJO獲得注入后可以直接執(zhí)行操作,不需要繼承什么基類,詳見JDBCTemplate參考文檔

               AplicationContext定義:

              <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
                  <property name="dataSource" ref="dataSource"/>
              </bean>

          實(shí)際使用: 

          SqlRowSet rs = jdbcTemplate.queryForRowSet(sql, params);

          Tips1: jdbcTemplate有很多的ORM化回調(diào)操作將返回結(jié)果轉(zhuǎn)為對(duì)象列表,但很多時(shí)候還是需要返回ResultSet,Spring有提供一個(gè)類似ResultSet的 Spring SqlRowSet對(duì)象。

                   

          Tips2:.注意jdbcTemplate盡量只執(zhí)行查詢操作,莫要進(jìn)行更新,否則很容易破壞Hibernate的二級(jí)緩存體系。


          Chapter 11. 使用JDBC進(jìn)行數(shù)據(jù)訪問(wèn)

          11.1. 簡(jiǎn)介

          Spring JDBC抽象框架所帶來(lái)的價(jià)值將在以下幾個(gè)方面得以體現(xiàn):(注:使用了Spring JDBC抽象框架之后,應(yīng)用開發(fā)人員只需要完成斜體字部分的編碼工作。)

          1. 指定數(shù)據(jù)庫(kù)連接參數(shù)

          2. 打開數(shù)據(jù)庫(kù)連接

          3. 聲明SQL語(yǔ)句

          4. 預(yù)編譯并執(zhí)行SQL語(yǔ)句

          5. 遍歷查詢結(jié)果(如果需要的話)

          6. 處理每一次遍歷操作

          7. 處理拋出的任何異常

          8. 處理事務(wù)

          9. 關(guān)閉數(shù)據(jù)庫(kù)連接

          Spring將替我們完成所有單調(diào)乏味的JDBC底層細(xì)節(jié)處理工作。

          11.1.1. Spring JDBC包結(jié)構(gòu)

          Spring JDBC抽象框架由四個(gè)包構(gòu)成:coredataSourceobject以及support

          org.springframework.jdbc.core包由JdbcTemplate類以及相關(guān)的回調(diào)接口(callback interface)和類組成。

          org.springframework.jdbc.datasource包由一些用來(lái)簡(jiǎn)化DataSource訪問(wèn)的工具類,以及各種DataSource接口的簡(jiǎn)單實(shí)現(xiàn)(主要用于單元測(cè)試以及在J2EE容器之外使用JDBC)組成。工具類提供了一些靜態(tài)方法,諸如通過(guò)JNDI獲取數(shù)據(jù)連接以及在必要的情況下關(guān)閉這些連接。它支持綁定線程的連接,比如被用于DataSourceTransactionManager的連接。

          接下來(lái),org.springframework.jdbc.object包由封裝了查詢、更新以及存儲(chǔ)過(guò)程的類組成,這些類的對(duì)象都是線程安全并且可重復(fù)使用的。它們類似于JDO,與JDO的不同之處在于查詢結(jié)果與數(shù)據(jù)庫(kù)是“斷開連接”的。它們是在org.springframework.jdbc.core包的基礎(chǔ)上對(duì)JDBC更高層次的抽象。

          最后,org.springframework.jdbc.support包提供了一些SQLException的轉(zhuǎn)換類以及相關(guān)的工具類。

          在JDBC處理過(guò)程中拋出的異常將被轉(zhuǎn)換成org.springframework.dao包中定義的異常。因此使用Spring JDBC進(jìn)行開發(fā)將不需要處理JDBC或者特定的RDBMS才會(huì)拋出的異常。所有的異常都是unchecked exception,這樣我們就可以對(duì)傳遞到調(diào)用者的異常進(jìn)行有選擇的捕獲。

          11.2. 利用JDBC核心類實(shí)現(xiàn)JDBC的基本操作和錯(cuò)誤處理

          11.2.1. JdbcTemplate

          JdbcTemplate是core包的核心類。它替我們完成了資源的創(chuàng)建以及釋放工作,從而簡(jiǎn)化了我們對(duì)JDBC的使用。它還可以幫助我們避免一些常見的錯(cuò)誤,比如忘記關(guān)閉數(shù)據(jù)庫(kù)連接。JdbcTemplate將完成JDBC核心處理流程,比如SQL語(yǔ)句的創(chuàng)建、執(zhí)行,而把SQL語(yǔ)句的生成以及查詢結(jié)果的提取工作留給我們的應(yīng)用代碼。它可以完成SQL查詢、更新以及調(diào)用存儲(chǔ)過(guò)程,可以對(duì)ResultSet進(jìn)行遍歷并加以提取。它還可以捕獲JDBC異常并將其轉(zhuǎn)換成org.springframework.dao包中定義的,通用的,信息更豐富的異常。

          使用JdbcTemplate進(jìn)行編碼只需要根據(jù)明確定義的一組契約來(lái)實(shí)現(xiàn)回調(diào)接口。PreparedStatementCreator回調(diào)接口通過(guò)給定的Connection創(chuàng)建一個(gè)PreparedStatement,包含SQL和任何相關(guān)的參數(shù)。CallableStatementCreateor實(shí)現(xiàn)同樣的處理,只不過(guò)它創(chuàng)建的是CallableStatement。RowCallbackHandler接口則從數(shù)據(jù)集的每一行中提取值。

          我們可以在一個(gè)service實(shí)現(xiàn)類中通過(guò)傳遞一個(gè)DataSource引用來(lái)完成JdbcTemplate的實(shí)例化,也可以在application context中配置一個(gè)JdbcTemplate bean,來(lái)供service使用。需要注意的是DataSource在application context總是配制成一個(gè)bean,第一種情況下,DataSource bean將傳遞給service,第二種情況下DataSource bean傳遞給JdbcTemplate bean。因?yàn)镴dbcTemplate使用回調(diào)接口和SQLExceptionTranslator接口作為參數(shù),所以一般情況下沒(méi)有必要通過(guò)繼承JdbcTemplate來(lái)定義其子類。

          JdbcTemplate中使用的所有SQL將會(huì)以“DEBUG”級(jí)別記入日志(一般情況下日志的category是JdbcTemplate相應(yīng)的全限定類名,不過(guò)如果需要對(duì)JdbcTemplate進(jìn)行定制的話,可能是它的子類名)。

          11.2.2. NamedParameterJdbcTemplate

          NamedParameterJdbcTemplate類增加了在SQL語(yǔ)句中使用命名參數(shù)的支持。在此之前,在傳統(tǒng)的SQL語(yǔ)句中,參數(shù)都是用'?'占位符來(lái)表示的。 NamedParameterJdbcTemplate類內(nèi)部封裝了一個(gè)普通的JdbcTemplate,并作為其代理來(lái)完成大部分工作。下面的內(nèi)容主要針對(duì)NamedParameterJdbcTemplateJdbcTemplate的不同之處來(lái)加以說(shuō)明,即如何在SQL語(yǔ)句中使用命名參數(shù)。

          通過(guò)下面的例子我們可以更好地了解NamedParameterJdbcTemplate的使用模式(在后面我們還有更好的使用方式)。

          // some JDBC-backed DAO class...
          public int countOfActorsByFirstName(String firstName) {
          String sql = "select count(0) from T_ACTOR where first_name = :first_name";
          NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(this.getDataSource());
          SqlParameterSource namedParameters = new MapSqlParameterSource("first_name", firstName);
          return template.queryForInt(sql, namedParameters);
          }

          在上面例子中,sql變量使用了命名參數(shù)占位符“first_name”,與其對(duì)應(yīng)的值存在namedParameters變量中(類型為MapSqlParameterSource)。

          如果你喜歡的話,也可以使用基于Map風(fēng)格的名值對(duì)將命名參數(shù)傳遞給NamedParameterJdbcTemplateNamedParameterJdbcTemplate實(shí)現(xiàn)了NamedParameterJdbcOperations接口,剩下的工作將由調(diào)用該接口的相應(yīng)方法來(lái)完成,這里我們就不再贅述):

          // some JDBC-backed DAO class...
          public int countOfActorsByFirstName(String firstName) {
          String sql = "select count(0) from T_ACTOR where first_name = :first_name";
          NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(this.getDataSource());
          Map namedParameters = new HashMap();
          namedParameters.put("first_name", firstName);
          return template.queryForInt(sql, namedParameters);
          }

          另外一個(gè)值得一提的特性是與NamedParameterJdbcTemplate位于同一個(gè)包中的SqlParameterSource接口。在前面的代碼片斷中我們已經(jīng)看到了該接口的實(shí)現(xiàn)(即MapSqlParameterSource類),SqlParameterSource可以用來(lái)作為NamedParameterJdbcTemplate命名參數(shù)的來(lái)源。MapSqlParameterSource類是一個(gè)非常簡(jiǎn)單的實(shí)現(xiàn),它僅僅是一個(gè)java.util.Map適配器,當(dāng)然其用法也就不言自明了(如果還有不明了的,可以在Spring的JIRA系統(tǒng)中要求提供更多的相關(guān)資料)。

          SqlParameterSource接口的另一個(gè)實(shí)現(xiàn)--BeanPropertySqlParameterSource為我們提供了更有趣的功能。該類包裝一個(gè)類似JavaBean的對(duì)象,所需要的命名參數(shù)值將由包裝對(duì)象提供,下面我們使用一個(gè)例子來(lái)更清楚地說(shuō)明它的用法。

          // some JavaBean-like class...
          public class Actor {
          private Long id;
          private String firstName;
          private String lastName;
          public String getFirstName() {
          return this.firstName;
          }
          public String getLastName() {
          return this.lastName;
          }
          public Long getId() {
          return this.id;
          }
          // setters omitted...
          }
          // some JDBC-backed DAO class...
          public int countOfActors(Actor exampleActor) {
          // notice how the named parameters match the properties of the above 'Actor' class
          String sql = "select count(0) from T_ACTOR where first_name = :firstName and last_name = :lastName";
          NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(this.getDataSource());
          SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(exampleActor);
          return template.queryForInt(sql, namedParameters);
          }

          大家必須牢記一點(diǎn):NamedParameterJdbcTemplate類內(nèi)部包裝了一個(gè)標(biāo)準(zhǔn)的JdbcTemplate類。如果你需要訪問(wèn)其內(nèi)部的JdbcTemplate實(shí)例(比如訪問(wèn)JdbcTemplate的一些方法)那么你需要使用getJdbcOperations()方法返回的JdbcOperations接口。(JdbcTemplate實(shí)現(xiàn)了JdbcOperations接口)。

          NamedParameterJdbcTemplate類是線程安全的,該類的最佳使用方式不是每次操作的時(shí)候?qū)嵗粋€(gè)新的NamedParameterJdbcTemplate,而是針對(duì)每個(gè)DataSource只配置一個(gè)NamedParameterJdbcTemplate實(shí)例(比如在Spring IoC容器中使用Spring IoC來(lái)進(jìn)行配置),然后在那些使用該類的DAO中共享該實(shí)例。

          11.2.3. SimpleJdbcTemplate

          [Note] Note

          請(qǐng)注意該類所提供的功能僅適用于Java 5 (Tiger)。

          SimpleJdbcTemplate類是JdbcTemplate類的一個(gè)包裝器(wrapper),它利用了Java 5的一些語(yǔ)言特性,比如Varargs和Autoboxing。對(duì)那些用慣了Java 5的程序員,這些新的語(yǔ)言特性還是很好用的。

          SimpleJdbcTemplate 類利用Java 5的語(yǔ)法特性帶來(lái)的好處可以通過(guò)一個(gè)例子來(lái)說(shuō)明。在下面的代碼片斷中我們首先使用標(biāo)準(zhǔn)的JdbcTemplate進(jìn)行數(shù)據(jù)訪問(wèn),接下來(lái)使用SimpleJdbcTemplate做同樣的事情。

          // classic JdbcTemplate-style...
          public Actor findActor(long id) {
          String sql = "select id, first_name, last_name from T_ACTOR where id = ?";
          RowMapper mapper = new RowMapper() {
          public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
          Actor actor = new Actor();
          actor.setId(rs.getLong(Long.valueOf(rs.getLong("id"))));
          actor.setFirstName(rs.getString("first_name"));
          actor.setLastName(rs.getString("last_name"));
          return actor;
          }
          };
          // normally this would be dependency injected of course...
          JdbcTemplate jdbcTemplate = new JdbcTemplate(this.getDataSource());
          // notice the cast, and the wrapping up of the 'id' argument
          // in an array, and the boxing of the 'id' argument as a reference type
          return (Actor) jdbcTemplate.queryForObject(sql, mapper, new Object[] {Long.valueOf(id)});
          }

          下面是同一方法的另一種實(shí)現(xiàn),惟一不同之處是我們使用了SimpleJdbcTemplate,這樣代碼顯得更加清晰。

          // SimpleJdbcTemplate-style...
          public Actor findActor(long id) {
          String sql = "select id, first_name, last_name from T_ACTOR where id = ?";
          ParameterizedRowMapper<Actor> mapper = new ParameterizedRowMapper<Actor>() {
          // notice the return type with respect to Java 5 covariant return types
          public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {
          Actor actor = new Actor();
          actor.setId(rs.getLong("id"));
          actor.setFirstName(rs.getString("first_name"));
          actor.setLastName(rs.getString("last_name"));
          return actor;
          }
          };
          // again, normally this would be dependency injected of course...
          SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(this.getDataSource());
          return simpleJdbcTemplate.queryForObject(sql, mapper, id);
          }

          11.2.4. DataSource接口

          為了從數(shù)據(jù)庫(kù)中取得數(shù)據(jù),我們首先需要獲取一個(gè)數(shù)據(jù)庫(kù)連接。 Spring通過(guò)DataSource對(duì)象來(lái)完成這個(gè)工作。 DataSource是JDBC規(guī)范的一部分, 它被視為一個(gè)通用的數(shù)據(jù)庫(kù)連接工廠。通過(guò)使用DataSource, Container或Framework可以將連接池以及事務(wù)管理的細(xì)節(jié)從應(yīng)用代碼中分離出來(lái)。 作為一個(gè)開發(fā)人員,在開發(fā)和測(cè)試產(chǎn)品的過(guò)程中,你可能需要知道連接數(shù)據(jù)庫(kù)的細(xì)節(jié)。 但在產(chǎn)品實(shí)施時(shí),你不需要知道這些細(xì)節(jié)。通常數(shù)據(jù)庫(kù)管理員會(huì)幫你設(shè)置好數(shù)據(jù)源。

          在使用Spring JDBC時(shí),你既可以通過(guò)JNDI獲得數(shù)據(jù)源,也可以自行配置數(shù)據(jù)源( 使用Spring提供的DataSource實(shí)現(xiàn)類)。使用后者可以更方便的脫離Web容器來(lái)進(jìn)行單元測(cè)試。 這里我們將使用DriverManagerDataSource,不過(guò)DataSource有多種實(shí)現(xiàn), 后面我們會(huì)講到。使用DriverManagerDataSource和你以前獲取一個(gè)JDBC連接 的做法沒(méi)什么兩樣。你首先必須指定JDBC驅(qū)動(dòng)程序的全限定名,這樣DriverManager 才能加載JDBC驅(qū)動(dòng)類,接著你必須提供一個(gè)url(因JDBC驅(qū)動(dòng)而異,為了保證設(shè)置正確請(qǐng)參考相關(guān)JDBC驅(qū)動(dòng)的文檔), 最后你必須提供一個(gè)用戶連接數(shù)據(jù)庫(kù)的用戶名和密碼。下面我們將通過(guò)一個(gè)例子來(lái)說(shuō)明如何配置一個(gè) DriverManagerDataSource

          DriverManagerDataSource dataSource = new DriverManagerDataSource();
          dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
          dataSource.setUrl("jdbc:hsqldb:hsql://localhost:");
          dataSource.setUsername("sa");
          dataSource.setPassword("");

          11.2.5. SQLExceptionTranslator接口

          SQLExceptionTranslator是一個(gè)接口,如果你需要在 SQLExceptionorg.springframework.dao.DataAccessException之間作轉(zhuǎn)換,那么必須實(shí)現(xiàn)該接口。

          轉(zhuǎn)換器類的實(shí)現(xiàn)可以采用一般通用的做法(比如使用JDBC的SQLState code),如果為了使轉(zhuǎn)換更準(zhǔn)確,也可以進(jìn)行定制(比如使用Oracle的error code)。

          SQLErrorCodeSQLExceptionTranslator是SQLExceptionTranslator的默認(rèn)實(shí)現(xiàn)。 該實(shí)現(xiàn)使用指定數(shù)據(jù)庫(kù)廠商的error code,比采用SQLState更精確。 轉(zhuǎn)換過(guò)程基于一個(gè)JavaBean(類型為SQLErrorCodes)中的error code。 這個(gè)JavaBean由SQLErrorCodesFactory工廠類創(chuàng)建,其中的內(nèi)容來(lái)自于 "sql-error-codes.xml"配置文件。該文件中的數(shù)據(jù)庫(kù)廠商代碼基于Database MetaData信息中的 DatabaseProductName,從而配合當(dāng)前數(shù)據(jù)庫(kù)的使用。

           

          SQLErrorCodeSQLExceptionTranslator使用以下的匹配規(guī)則:

           

          • 首先檢查是否存在完成定制轉(zhuǎn)換的子類實(shí)現(xiàn)。通常SQLErrorCodeSQLExceptionTranslator 這個(gè)類可以作為一個(gè)具體類使用,不需要進(jìn)行定制,那么這個(gè)規(guī)則將不適用。

          • 接著將SQLException的error code與錯(cuò)誤代碼集中的error code進(jìn)行匹配。 默認(rèn)情況下錯(cuò)誤代碼集將從SQLErrorCodesFactory取得。 錯(cuò)誤代碼集來(lái)自classpath下的sql-error-codes.xml文件, 它們將與數(shù)據(jù)庫(kù)metadata信息中的database name進(jìn)行映射。

          • 如果仍然無(wú)法匹配,最后將調(diào)用fallbackTranslator屬性的translate方法,SQLStateSQLExceptionTranslator類實(shí)例是默認(rèn)的fallbackTranslator。

           

          SQLErrorCodeSQLExceptionTranslator可以采用下面的方式進(jìn)行擴(kuò)展:

          public class MySQLErrorCodesTranslator extends SQLErrorCodeSQLExceptionTranslator {
          protected DataAccessException customTranslate(String task, String sql, SQLException sqlex) {
          if (sqlex.getErrorCode() == -12345) {
          return new DeadlockLoserDataAccessException(task, sqlex);
          }
          return null;
          }
          }

          在上面的這個(gè)例子中,error code為'-12345'的SQLException 將采用該轉(zhuǎn)換器進(jìn)行轉(zhuǎn)換,而其他的error code將由默認(rèn)的轉(zhuǎn)換器進(jìn)行轉(zhuǎn)換。 為了使用該轉(zhuǎn)換器,必須將其作為參數(shù)傳遞給JdbcTemplate類 的setExceptionTranslator方法,并在需要使用這個(gè)轉(zhuǎn)換器器的數(shù)據(jù) 存取操作中使用該JdbcTemplate。 下面的例子演示了如何使用該定制轉(zhuǎn)換器:

          // create a JdbcTemplate and set data source
          JdbcTemplate jt = new JdbcTemplate();
          jt.setDataSource(dataSource);
          // create a custom translator and set the DataSource for the default translation lookup
          MySQLErrorCodesTransalator tr = new MySQLErrorCodesTransalator();
          tr.setDataSource(dataSource);
          jt.setExceptionTranslator(tr);
          // use the JdbcTemplate for this SqlUpdate
          SqlUpdate su = new SqlUpdate();
          su.setJdbcTemplate(jt);
          su.setSql("update orders set shipping_charge = shipping_charge * 1.05");
          su.compile();
          su.update();

          在上面的定制轉(zhuǎn)換器中,我們給它注入了一個(gè)數(shù)據(jù)源,因?yàn)槲覀內(nèi)匀恍枰?使用默認(rèn)的轉(zhuǎn)換器從sql-error-codes.xml中獲取錯(cuò)誤代碼集。

          11.2.6. 執(zhí)行SQL語(yǔ)句

          我們僅需要非常少的代碼就可以達(dá)到執(zhí)行SQL語(yǔ)句的目的,一旦獲得一個(gè) DataSource和一個(gè)JdbcTemplate, 我們就可以使用JdbcTemplate提供的豐富功能實(shí)現(xiàn)我們的操作。 下面的例子使用了極少的代碼完成創(chuàng)建一張表的工作。

          import javax.sql.DataSource;
          import org.springframework.jdbc.core.JdbcTemplate;
          public class ExecuteAStatement {
          private JdbcTemplate jt;
          private DataSource dataSource;
          public void doExecute() {
          jt = new JdbcTemplate(dataSource);
          jt.execute("create table mytable (id integer, name varchar(100))");
          }
          public void setDataSource(DataSource dataSource) {
          this.dataSource = dataSource;
          }
          }

          11.2.7. 執(zhí)行查詢

          除了execute方法之外,JdbcTemplate還提供了大量的查詢方法。 在這些查詢方法中,有很大一部分是用來(lái)查詢單值的。比如返回一個(gè)匯總(count)結(jié)果 或者從返回行結(jié)果中取得指定列的值。這時(shí)我們可以使用queryForInt(..)queryForLong(..)或者queryForObject(..)方法。 queryForObject方法用來(lái)將返回的JDBC類型對(duì)象轉(zhuǎn)換成指定的Java對(duì)象,如果類型轉(zhuǎn)換失敗將拋出 InvalidDataAccessApiUsageException異常。 下面的例子演示了兩個(gè)查詢的用法,一個(gè)返回int值,另一個(gè)返回 String

          import javax.sql.DataSource;
          import org.springframework.jdbc.core.JdbcTemplate;
          public class RunAQuery {
          private JdbcTemplate jt;
          private DataSource dataSource;
          public int getCount() {
          jt = new JdbcTemplate(dataSource);
          int count = jt.queryForInt("select count(*) from mytable");
          return count;
          }
          public String getName() {
          jt = new JdbcTemplate(dataSource);
          String name = (String) jt.queryForObject("select name from mytable", String.class);
          return name;
          }
          public void setDataSource(DataSource dataSource) {
          this.dataSource = dataSource;
          }
          }

          除了返回單值的查詢方法,JdbcTemplate還提供了一組返回List結(jié)果 的方法。List中的每一項(xiàng)對(duì)應(yīng)查詢返回結(jié)果中的一行。其中最簡(jiǎn)單的是queryForList方法, 該方法將返回一個(gè)List,該List中的每一條 記錄是一個(gè)Map對(duì)象,對(duì)應(yīng)應(yīng)數(shù)據(jù)庫(kù)中某一行;而該Map 中的每一項(xiàng)對(duì)應(yīng)該數(shù)據(jù)庫(kù)行中的某一列值。下面的代碼片斷接著上面的例子演示了如何用該方法返回表中 所有記錄:

          public List getList() {
          jt = new JdbcTemplate(dataSource);
          List rows = jt.queryForList("select * from mytable");
          return rows;
          }

          返回的結(jié)果集類似下面這種形式:

          [{name=Bob, id=1}, {name=Mary, id=2}]

          11.2.8. 更新數(shù)據(jù)庫(kù)

          JdbcTemplate還提供了一些更新數(shù)據(jù)庫(kù)的方法。 在下面的例子中,我們根據(jù)給定的主鍵值對(duì)指定的列進(jìn)行更新。 例子中的SQL語(yǔ)句中使用了“?”占位符來(lái)接受參數(shù)(這種做法在更新和查詢SQL語(yǔ)句中很常見)。 傳遞的參數(shù)值位于一個(gè)對(duì)象數(shù)組中(基本類型需要被包裝成其對(duì)應(yīng)的對(duì)象類型)。

          import javax.sql.DataSource;
          import org.springframework.jdbc.core.JdbcTemplate;
          public class ExecuteAnUpdate {
          private JdbcTemplate jt;
          private DataSource dataSource;
          public void setName(int id, String name) {
          jt = new JdbcTemplate(dataSource);
          jt.update("update mytable set name = ? where id = ?", new Object[] {name, new Integer(id)});
          }
          public void setDataSource(DataSource dataSource) {
          this.dataSource = dataSource;
          }
          }

          11.3. 控制數(shù)據(jù)庫(kù)連接

          11.3.1. DataSourceUtils

          DataSourceUtils作為一個(gè)幫助類提供易用且強(qiáng)大的數(shù)據(jù)庫(kù)訪問(wèn)能力, 我們可以使用該類提供的靜態(tài)方法從JNDI獲取數(shù)據(jù)庫(kù)連接以及在必要的時(shí)候關(guān)閉之。 它提供支持線程綁定的數(shù)據(jù)庫(kù)連接(比如使用DataSourceTransactionManager 的時(shí)候,將把數(shù)據(jù)庫(kù)連接綁定到當(dāng)前的線程上)。

          注:getDataSourceFromJndi(..)方法主要用于那些沒(méi)有使用bean factory 或者application context的場(chǎng)合。如果使用application context,那么最好是在 JndiObjectFactoryBean中配置bean或者直接使用 JdbcTemplate實(shí)例。JndiObjectFactoryBean 能夠通過(guò)JNDI獲取DataSource并將 DataSource作為引用參數(shù)傳遞給其他bean。 這樣,在不同的DataSource之間切換只需要修改配置文件即可, 甚至我們可以用一個(gè)非JNDI的DataSource來(lái)替換 FactoryBean定義!

          11.3.2. SmartDataSource接口

          SmartDataSourceDataSource 接口的一個(gè)擴(kuò)展,用來(lái)提供數(shù)據(jù)庫(kù)連接。使用該接口的類在指定的操作之后可以檢查是否需要關(guān)閉連接。 該接口在某些情況下非常有用,比如有些情況需要重用數(shù)據(jù)庫(kù)連接。

          11.3.3. AbstractDataSource

          AbstractDataSource是一個(gè)實(shí)現(xiàn)了DataSource 接口的abstract基類。它實(shí)現(xiàn)了DataSource接口的 一些無(wú)關(guān)痛癢的方法,如果你需要實(shí)現(xiàn)自己的DataSource,那么繼承 該類是個(gè)好主意。

          11.3.4. SingleConnectionDataSource

          SingleConnectionDataSourceSmartDataSource接口 的一個(gè)實(shí)現(xiàn),其內(nèi)部包裝了一個(gè)單連接。該連接在使用之后將不會(huì)關(guān)閉,很顯然它不能在多線程 的環(huán)境下使用。

          當(dāng)客戶端代碼調(diào)用close方法的時(shí)候,如果它總是假設(shè)數(shù)據(jù)庫(kù)連接來(lái)自連接池(就像使用持久化工具時(shí)一樣), 你應(yīng)該將suppressClose設(shè)置為true。 這樣,通過(guò)該類獲取的將是代理連接(禁止關(guān)閉)而不是原有的物理連接。 需要注意的是,我們不能把使用該類獲取的數(shù)據(jù)庫(kù)連接造型(cast)為Oracle Connection之類的本地?cái)?shù)據(jù)庫(kù)連接。

          SingleConnectionDataSource主要在測(cè)試的時(shí)候使用。 它使得測(cè)試代碼很容易脫離應(yīng)用服務(wù)器而在一個(gè)簡(jiǎn)單的JNDI環(huán)境下運(yùn)行。 與DriverManagerDataSource不同的是,它始終只會(huì)使用同一個(gè)數(shù)據(jù)庫(kù)連接, 從而避免每次建立物理連接的開銷。

          11.3.5. DriverManagerDataSource

          DriverManagerDataSource類實(shí)現(xiàn)了 SmartDataSource接口。在applicationContext.xml中可以使用 bean properties來(lái)設(shè)置JDBC Driver屬性,該類每次返回的都是一個(gè)新的連接。

          該類主要在測(cè)試以及脫離J2EE容器的獨(dú)立環(huán)境中使用。它既可以用來(lái)在application context中作為一個(gè) DataSource bean,也可以在簡(jiǎn)單的JNDI環(huán)境下使用。 由于Connection.close()僅僅只是簡(jiǎn)單的關(guān)閉數(shù)據(jù)庫(kù)連接,因此任何能夠獲取 DataSource的持久化代碼都能很好的工作。不過(guò)使用JavaBean風(fēng)格的連接池 (比如commons-dbcp)也并非難事。即使是在測(cè)試環(huán)境下,使用連接池也是一種比使用 DriverManagerDataSource更好的做法。

          11.3.6. TransactionAwareDataSourceProxy

          TransactionAwareDataSourceProxy作為目標(biāo)DataSource的一個(gè)代理, 在對(duì)目標(biāo)DataSource包裝的同時(shí),還增加了Spring的事務(wù)管理能力, 在這一點(diǎn)上,這個(gè)類的功能非常像J2EE服務(wù)器所提供的事務(wù)化的JNDI DataSource

          [Note] Note

          該類幾乎很少被用到,除非現(xiàn)有代碼在被調(diào)用的時(shí)候需要一個(gè)標(biāo)準(zhǔn)的 JDBC DataSource接口實(shí)現(xiàn)作為參數(shù)。 這種情況下,這個(gè)類可以使現(xiàn)有代碼參與Spring的事務(wù)管理。通常最好的做法是使用更高層的抽象 來(lái)對(duì)數(shù)據(jù)源進(jìn)行管理,比如JdbcTemplateDataSourceUtils等等。

          如果需要更詳細(xì)的資料,請(qǐng)參考TransactionAwareDataSourceProxy JavaDoc 。

          11.3.7. DataSourceTransactionManager

          DataSourceTransactionManager類是 PlatformTransactionManager接口的一個(gè)實(shí)現(xiàn),用于處理單JDBC數(shù)據(jù)源。 它將從指定DataSource取得的JDBC連接綁定到當(dāng)前線程,因此它也支持了每個(gè)數(shù)據(jù)源對(duì)應(yīng)到一個(gè)線程。

          我們推薦在應(yīng)用代碼中使用DataSourceUtils.getConnection(DataSource)來(lái)獲取 JDBC連接,而不是使用J2EE標(biāo)準(zhǔn)的DataSource.getConnection。因?yàn)榍罢邔伋?unchecked的org.springframework.dao異常,而不是checked的 SQLException異常。Spring Framework中所有的類(比如 JdbcTemplate)都采用這種做法。如果不需要和這個(gè) DataSourceTransactionManager類一起使用,DataSourceUtils 提供的功能跟一般的數(shù)據(jù)庫(kù)連接策略沒(méi)有什么兩樣,因此它可以在任何場(chǎng)景下使用。

          DataSourceTransactionManager類支持定制隔離級(jí)別,以及對(duì)SQL語(yǔ)句查詢超時(shí)的設(shè)定。 為了支持后者,應(yīng)用代碼必須使用JdbcTemplate或者在每次創(chuàng)建SQL語(yǔ)句時(shí)調(diào)用 DataSourceUtils.applyTransactionTimeout方法。

          在使用單個(gè)數(shù)據(jù)源的情形下,你可以用DataSourceTransactionManager來(lái)替代JtaTransactionManager, 因?yàn)?tt class="classname">DataSourceTransactionManager不需要容器支持JTA。如果你使用DataSourceUtils.getConnection(DataSource)來(lái)獲取 JDBC連接,二者之間的切換只需要更改一些配置。最后需要注意的一點(diǎn)就是JtaTransactionManager不支持隔離級(jí)別的定制!

          11.4. 用Java對(duì)象來(lái)表達(dá)JDBC操作

          org.springframework.jdbc.object包下的類允許用戶以更加 面向?qū)ο蟮姆绞饺ピL問(wèn)數(shù)據(jù)庫(kù)。比如說(shuō),用戶可以執(zhí)行查詢并返回一個(gè)list, 該list作為一個(gè)結(jié)果集將把從數(shù)據(jù)庫(kù)中取出的列數(shù)據(jù)映射到業(yè)務(wù)對(duì)象的屬性上。 用戶也可以執(zhí)行存儲(chǔ)過(guò)程,以及運(yùn)行更新、刪除以及插入SQL語(yǔ)句。

          [Note] Note

          在許多Spring開發(fā)人員中間存在有一種觀點(diǎn),那就是下面將要提到的各種RDBMS操作類 (StoredProcedure類除外) 通常也可以直接使用JdbcTemplate相關(guān)的方法來(lái)替換。 相對(duì)于把一個(gè)查詢操作封裝成一個(gè)類而言,直接調(diào)用JdbcTemplate方法將更簡(jiǎn)單 而且更容易理解。

          必須說(shuō)明的一點(diǎn)就是,這僅僅只是一種觀點(diǎn)而已, 如果你認(rèn)為你可以從直接使用RDBMS操作類中獲取一些額外的好處, 你不妨根據(jù)自己的需要和喜好進(jìn)行不同的選擇。

          11.4.1. SqlQuery

          SqlQuery是一個(gè)可重用、線程安全的類,它封裝了一個(gè)SQL查詢。 其子類必須實(shí)現(xiàn)newResultReader()方法,該方法用來(lái)在遍歷 ResultSet的時(shí)候能使用一個(gè)類來(lái)保存結(jié)果。 我們很少需要直接使用SqlQuery,因?yàn)槠渥宇?MappingSqlQuery作為一個(gè)更加易用的實(shí)現(xiàn)能夠?qū)⒔Y(jié)果集中的行映射為Java對(duì)象。 SqlQuery還有另外兩個(gè)擴(kuò)展分別是 MappingSqlQueryWithParametersUpdatableSqlQuery

          11.4.2. MappingSqlQuery

          MappingSqlQuery是一個(gè)可重用的查詢抽象類,其具體類必須實(shí)現(xiàn) mapRow(ResultSet, int)抽象方法來(lái)將結(jié)果集中的每一行轉(zhuǎn)換成Java對(duì)象。

          SqlQuery的各種實(shí)現(xiàn)中, MappingSqlQuery是最常用也是最容易使用的一個(gè)。

          下面這個(gè)例子演示了一個(gè)定制查詢,它將從客戶表中取得的數(shù)據(jù)映射到一個(gè) Customer類實(shí)例。

          private class CustomerMappingQuery extends MappingSqlQuery {
          public CustomerMappingQuery(DataSource ds) {
          super(ds, "SELECT id, name FROM customer WHERE id = ?");
          super.declareParameter(new SqlParameter("id", Types.INTEGER));
          compile();
          }
          public Object mapRow(ResultSet rs, int rowNumber) throws SQLException {
          Customer cust = new Customer();
          cust.setId((Integer) rs.getObject("id"));
          cust.setName(rs.getString("name"));
          return cust;
          }
          }

          在上面的例子中,我們?yōu)橛脩舨樵兲峁┝艘粋€(gè)構(gòu)造函數(shù)并為構(gòu)造函數(shù)傳遞了一個(gè) DataSource參數(shù)。在構(gòu)造函數(shù)里面我們把 DataSource和一個(gè)用來(lái)返回查詢結(jié)果的SQL語(yǔ)句作為參數(shù) 調(diào)用父類的構(gòu)造函數(shù)。SQL語(yǔ)句將被用于生成一個(gè)PreparedStatement對(duì)象, 因此它可以包含占位符來(lái)傳遞參數(shù)。而每一個(gè)SQL語(yǔ)句的參數(shù)必須通過(guò)調(diào)用 declareParameter方法來(lái)進(jìn)行聲明,該方法需要一個(gè) SqlParameter(封裝了一個(gè)字段名字和一個(gè) java.sql.Types中定義的JDBC類型)對(duì)象作為參數(shù)。 所有參數(shù)定義完之后,我們調(diào)用compile()方法來(lái)對(duì)SQL語(yǔ)句進(jìn)行預(yù)編譯。

          下面讓我們看看該定制查詢初始化并執(zhí)行的代碼:

          public Customer getCustomer(Integer id) {
          CustomerMappingQuery custQry = new CustomerMappingQuery(dataSource);
          Object[] parms = new Object[1];
          parms[0] = id;
          List customers = custQry.execute(parms);
          if (customers.size() > 0) {
          return (Customer) customers.get(0);
          }
          else {
          return null;
          }
          }

          在上面的例子中,getCustomer方法通過(guò)傳遞惟一參數(shù)id來(lái)返回一個(gè)客戶對(duì)象。 該方法內(nèi)部在創(chuàng)建CustomerMappingQuery實(shí)例之后, 我們創(chuàng)建了一個(gè)對(duì)象數(shù)組用來(lái)包含要傳遞的查詢參數(shù)。這里我們只有唯一的一個(gè) Integer參數(shù)。執(zhí)行CustomerMappingQuery的 execute方法之后,我們得到了一個(gè)List,該List中包含一個(gè) Customer對(duì)象,如果有對(duì)象滿足查詢條件的話。

          11.4.3. SqlUpdate

          SqlUpdate類封裝了一個(gè)可重復(fù)使用的SQL更新操作。 跟所有RdbmsOperation類一樣,SqlUpdate可以在SQL中定義參數(shù)。

          該類提供了一系列update()方法,就像SqlQuery提供的一系列execute()方法一樣。

          SqlUpdate是一個(gè)具體的類。通過(guò)在SQL語(yǔ)句中定義參數(shù),這個(gè)類可以支持 不同的更新方法,我們一般不需要通過(guò)繼承來(lái)實(shí)現(xiàn)定制。

          import java.sql.Types;
          import javax.sql.DataSource;
          import org.springframework.jdbc.core.SqlParameter;
          import org.springframework.jdbc.object.SqlUpdate;
          public class UpdateCreditRating extends SqlUpdate {
          public UpdateCreditRating(DataSource ds) {
          setDataSource(ds);
          setSql("update customer set credit_rating = ? where id = ?");
          declareParameter(new SqlParameter(Types.NUMERIC));
          declareParameter(new SqlParameter(Types.NUMERIC));
          compile();
          }
          /**
          * @param id for the Customer to be updated
          * @param rating the new value for credit rating
          * @return number of rows updated
          */
          public int run(int id, int rating) {
          Object[] params =
          new Object[] {
          new Integer(rating),
          new Integer(id)};
          return update(params);
          }
          }

          11.4.4. StoredProcedure

          StoredProcedure類是一個(gè)抽象基類,它是對(duì)RDBMS存儲(chǔ)過(guò)程的一種抽象。 該類提供了多種execute(..)方法,不過(guò)這些方法的訪問(wèn)類型都是protected的。

          從父類繼承的sql屬性用來(lái)指定RDBMS存儲(chǔ)過(guò)程的名字。 盡管該類提供了許多必須在JDBC3.0下使用的功能,但是我們更關(guān)注的是JDBC 3.0中引入的命名參數(shù)特性。

          下面的程序演示了如何調(diào)用Oracle中的sysdate()函數(shù)。 這里我們創(chuàng)建了一個(gè)繼承StoredProcedure的子類,雖然它沒(méi)有輸入?yún)?shù), 但是我必須通過(guò)使用SqlOutParameter來(lái)聲明一個(gè)日期類型的輸出參數(shù)。 execute()方法將返回一個(gè)map,map中的每個(gè)entry是一個(gè)用參數(shù)名作key, 以輸出參數(shù)為value的名值對(duì)。

          import java.sql.Types;
          import java.util.HashMap;
          import java.util.Iterator;
          import java.util.Map;
          import javax.sql.DataSource;
          import org.springframework.jdbc.core.SqlOutParameter;
          import org.springframework.jdbc.datasource.*;
          import org.springframework.jdbc.object.StoredProcedure;
          public class TestStoredProcedure {
          public static void main(String[] args)  {
          TestStoredProcedure t = new TestStoredProcedure();
          t.test();
          System.out.println("Done!");
          }
          void test() {
          DriverManagerDataSource ds = new DriverManagerDataSource();
          ds.setDriverClassName("oracle.jdbc.OracleDriver");
          ds.setUrl("jdbc:oracle:thin:@localhost:1521:mydb");
          ds.setUsername("scott");
          ds.setPassword("tiger");
          MyStoredProcedure sproc = new MyStoredProcedure(ds);
          Map results = sproc.execute();
          printMap(results);
          }
          private class MyStoredProcedure extends StoredProcedure {
          private static final String SQL = "sysdate";
          public MyStoredProcedure(DataSource ds) {
          setDataSource(ds);
          setFunction(true);
          setSql(SQL);
          declareParameter(new SqlOutParameter("date", Types.DATE));
          compile();
          }
          public Map execute() {
          // the 'sysdate' sproc has no input parameters, so an empty Map is supplied...
          return execute(new HashMap());
          }
          }
          private static void printMap(Map results) {
          for (Iterator it = results.entrySet().iterator(); it.hasNext(); ) {
          System.out.println(it.next());
          }
          }
          }

          下面是StoredProcedure的另一個(gè)例子,它使用了兩個(gè)Oracle游標(biāo)類型的輸出參數(shù)。

          import oracle.jdbc.driver.OracleTypes;
          import org.springframework.jdbc.core.SqlOutParameter;
          import org.springframework.jdbc.object.StoredProcedure;
          import javax.sql.DataSource;
          import java.util.HashMap;
          import java.util.Map;
          public class TitlesAndGenresStoredProcedure extends StoredProcedure {
          private static final String SPROC_NAME = "AllTitlesAndGenres";
          public TitlesAndGenresStoredProcedure(DataSource dataSource) {
          super(dataSource, SPROC_NAME);
          declareParameter(new SqlOutParameter("titles", OracleTypes.CURSOR, new TitleMapper()));
          declareParameter(new SqlOutParameter("genres", OracleTypes.CURSOR, new GenreMapper()));
          compile();
          }
          public Map execute() {
          // again, this sproc has no input parameters, so an empty Map is supplied...
          return super.execute(new HashMap());
          }
          }

          值得注意的是TitlesAndGenresStoredProcedure構(gòu)造函數(shù)中 declareParameter(..)SqlOutParameter參數(shù), 該參數(shù)使用了RowMapper接口的實(shí)現(xiàn)。 這是一種非常方便而強(qiáng)大的重用方式。 下面我們來(lái)看一下RowMapper的兩個(gè)具體實(shí)現(xiàn)。

          首先是TitleMapper類,它簡(jiǎn)單的把ResultSet中的每一行映射為一個(gè)Title Domain Object。

          import com.foo.sprocs.domain.Title;
          import org.springframework.jdbc.core.RowMapper;
          import java.sql.ResultSet;
          import java.sql.SQLException;
          public final class TitleMapper implements RowMapper {
          public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
          Title title = new Title();
          title.setId(rs.getLong("id"));
          title.setName(rs.getString("name"));
          return title;
          }
          }

          另一個(gè)是GenreMapper類,也是非常簡(jiǎn)單的將ResultSet中的每一行映射為一個(gè)Genre Domain Object。

          import org.springframework.jdbc.core.RowMapper;
          import java.sql.ResultSet;
          import java.sql.SQLException;
          import com.foo.domain.Genre;
          public final class GenreMapper implements RowMapper {
          public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
          return new Genre(rs.getString("name"));
          }
          }

          如果你需要給存儲(chǔ)過(guò)程傳輸入?yún)?shù)(這些輸入?yún)?shù)是在RDBMS存儲(chǔ)過(guò)程中定義好了的), 則需要提供一個(gè)指定類型的execute(..)方法, 該方法將調(diào)用基類的protected execute(Map parameters)方法。 例如:

          import oracle.jdbc.driver.OracleTypes;
          import org.springframework.jdbc.core.SqlOutParameter;
          import org.springframework.jdbc.object.StoredProcedure;
          import javax.sql.DataSource;
          import java.util.HashMap;
          import java.util.Map;
          public class TitlesAfterDateStoredProcedure extends StoredProcedure {
          private static final String SPROC_NAME = "TitlesAfterDate";
          private static final String CUTOFF_DATE_PARAM = "cutoffDate";
          public TitlesAfterDateStoredProcedure(DataSource dataSource) {
          super(dataSource, SPROC_NAME);
          declaraParameter(new SqlParameter(CUTOFF_DATE_PARAM, Types.DATE);
          declareParameter(new SqlOutParameter("titles", OracleTypes.CURSOR, new TitleMapper()));
          compile();
          }
          public Map execute(Date cutoffDate) {
          Map inputs = new HashMap();
          inputs.put(CUTOFF_DATE_PARAM, cutoffDate);
          return super.execute(inputs);
          }
          }

          11.4.5. SqlFunction

          SqlFunction RDBMS操作類封裝了一個(gè)SQL“函數(shù)”包裝器(wrapper), 該包裝器適用于查詢并返回一個(gè)單行結(jié)果集。默認(rèn)返回的是一個(gè)int值, 不過(guò)我們可以采用類似JdbcTemplate中的queryForXxx 做法自己實(shí)現(xiàn)來(lái)返回其它類型。SqlFunction優(yōu)勢(shì)在于我們不必創(chuàng)建 JdbcTemplate,這些它都在內(nèi)部替我們做了。

          該類的主要用途是調(diào)用SQL函數(shù)來(lái)返回一個(gè)單值的結(jié)果集,比如類似“select user()”、 “select sysdate from dual”的查詢。如果需要調(diào)用更復(fù)雜的存儲(chǔ)函數(shù), 可以使用StoredProcedureSqlCall

          SqlFunction是一個(gè)具體類,通常我們不需要它的子類。 其用法是創(chuàng)建該類的實(shí)例,然后聲明SQL語(yǔ)句以及參數(shù)就可以調(diào)用相關(guān)的run方法去多次執(zhí)行函數(shù)。 下面的例子用來(lái)返回指定表的記錄行數(shù):

          public int countRows() {
          SqlFunction sf = new SqlFunction(dataSource, "select count(*) from mytable");
          sf.compile();
          return sf.run();
          }
          posted @ 2009-03-15 11:27 java_蟈蟈 閱讀(58122) | 評(píng)論 (2)編輯 收藏

           因前段時(shí)間碰到j(luò)ava.lang.OutOfMemoryError: PermGen space問(wèn)題,想到檢控TOMCAT及調(diào)優(yōu)問(wèn)題,從網(wǎng)上搜到這個(gè)工具,一開始配置了N久后也未配起來(lái),后來(lái)偶然間配置好了,隨把過(guò)程寫到此,以便共享

          測(cè)試:tomcat5+jprofiler_windows_5_1_4 它的注冊(cè)碼可到官網(wǎng)上注冊(cè)一個(gè),免費(fèi)試用,當(dāng)然是有期限的

          有的時(shí)候Tomcat跑Web應(yīng)用會(huì)慢慢死掉,CPU 100%占用。一般情況下是程序哪里出了問(wèn)題,慢慢的DEBUG,幾乎翻遍所有的代碼,是不是很累?這里介紹一下JProfiler,比較優(yōu)秀的性能監(jiān)控和分析工具。
          JProfiler我用的是4.3.3版本,他是收費(fèi)的,不過(guò)google上面很多注冊(cè)碼可供使用。
          安裝的時(shí)候會(huì)提示一些比如尋找JVM等過(guò)程,這里就不多說(shuō)了。安裝完JProfiler,運(yùn)行,出現(xiàn)如下界面:

          由于我們是要?jiǎng)?chuàng)建對(duì)本地tomcat的監(jiān)控,選擇an application server,locally or remotely.
          在接下來(lái)的窗口中,選擇tomcat及版本,

          下一步,選擇本地:

          下一步,選擇啟動(dòng)批處理文件


          注意,這里的選擇如果你是TOMCAT5的話,如果選擇startup.bat跑不起來(lái),你不防把它配置成tomcat.exe我就是在這里卡住了

          下一步,選擇JVM類型:

          接著選擇JProfiler的監(jiān)聽端口:

          接著,選擇直接啟動(dòng):

          下面會(huì)有一個(gè)很重要的提示,可能很多人在這里都沒(méi)有注意而總是配置不好JProfiler:

          上面標(biāo)紅的配置好后,這下面的根本不用配置就可以跑起來(lái)了

          第一,需要把
          -agentlib:jprofilerti=port=8849,nowait,id=103,config=C:\Documents and Settings\stefanie_wu\.jprofiler4\config.xml"
          "-Xbootclasspath/a:D:\Program Files\jprofiler4\bin\agent.jar" -Xbootclasspath/a:D:\usr\agent.jar
          兩個(gè)參數(shù)加載啟動(dòng)項(xiàng)中,
          第二,要把D:\Program Files\jprofiler4\bin\windows放在PATH中。

          我是使用.bat來(lái)啟動(dòng)tomcat的,所以在startup.bat中加入一段代碼:
          set JAVA_OPTS=%JAVA_OPTS% -agentlib:jprofilerti=port=8849,nowait,id=103,config=C:\Documents and Settings\stefanie_wu\.jprofiler4\config.xml -Xbootclasspath/a:D:\Program Files\jprofiler4\bin\agent.jar" -Xbootclasspath/a:D:\usr\agent.jar
          但是這樣啟動(dòng)會(huì)有問(wèn)題,因?yàn)槠渲新窂桨丝崭瘢?br /> 所以拷貝comfig.xml和agent.jar到一個(gè)新的路徑下面,比如:
          set JAVA_OPTS=%JAVA_OPTS% -agentlib:jprofilerti=port=8849,nowait,id=102,config=D:\usr\config.xml -Xbootclasspath/a:D:\usr\agent.jar

          這里的jprofilerti=port=8849就是剛才設(shè)置的jprofiler監(jiān)控端口。
          設(shè)置完這些,通過(guò)startup.bat啟動(dòng)tomcat,然后

          點(diǎn)OK

          posted @ 2009-01-14 01:39 java_蟈蟈 閱讀(4710) | 評(píng)論 (0)編輯 收藏

          今日整到此處,特將網(wǎng)上搜刮來(lái)的信息貼于此,以供大家共享之

          window.onbeforeunload = function()   
          {   var n = window.event.screenX - window.screenLeft;      
              var b = n > document.documentElement.scrollWidth-20;      
           if(b && window.event.clientY < 0 || window.event.altKey)   
           {   
           //window.event.returnValue = "1111";      
           userBaseDAO.upIsLogin(${adminbean.id});
           }    
          }    

          三大主流瀏覽器中firefox和IE都支持onbeforeunload事件,opera尚未支持。

          用法:

          • object.onbeforeunload = handler
          • <element onbeforeunload = “handler” … ></element>

          描述:
          事件觸發(fā)的時(shí)候彈出一個(gè)有確定和取消的對(duì)話框,確定則離開頁(yè)面,取消則繼續(xù)待在本頁(yè)。
          handler可以設(shè)一個(gè)返回值作為該對(duì)話框的顯示文本。

          觸發(fā)于:

          • 關(guān)閉瀏覽器窗口
          • 通過(guò)地址欄或收藏夾前往其他頁(yè)面的時(shí)候
          • 點(diǎn)擊返回,前進(jìn),刷新,主頁(yè)其中一個(gè)的時(shí)候
          • 點(diǎn)擊 一個(gè)前往其他頁(yè)面的url連接的時(shí)候
          • 調(diào)用以下任意一個(gè)事件的時(shí)候:click,document write,document open,document close,window close ,window navigate ,window NavigateAndFind,location replace,location reload,form submit.
          • 當(dāng)用window open打開一個(gè)頁(yè)面,并把本頁(yè)的window的名字傳給要打開的頁(yè)面的時(shí)候。
          • 重新賦予location.href的值的時(shí)候。
          • 通過(guò)input type=”submit”按鈕提交一個(gè)具有指定action的表單的時(shí)候。

          可以用在以下元素:
          BODY, FRAMESET, window

          平臺(tái)支持:
          IE4+/Win, Mozilla 1.7a+, Netscape 7.2+, Firefox0.9+


           

          標(biāo)簽只有onload\onunload\onbeforeunload事件,而沒(méi)有onclose事件。不管頁(yè)面是關(guān)閉還是刷新都會(huì)執(zhí)行onunload事件。如何捕捉到頁(yè)面關(guān)閉呢?
          頁(yè)面加載時(shí)只執(zhí)行onload
          頁(yè)面關(guān)閉時(shí)只執(zhí)行onunload
          頁(yè)面刷新時(shí)先執(zhí)行onbeforeunload,然后onunload,最后onload。這樣我們可以在onbeforeunload中加一個(gè)標(biāo)記,在onunload中判斷該標(biāo)記,即可達(dá)到判斷頁(yè)面是否真的關(guān)閉了。
          posted @ 2008-12-08 20:00 java_蟈蟈 閱讀(7868) | 評(píng)論 (2)編輯 收藏

               摘要: DAO模式是標(biāo)準(zhǔn)的J2EE設(shè)計(jì)模式之一.開發(fā)人員使用這個(gè)模式把底層的數(shù)據(jù)訪問(wèn)操作和上層的商務(wù)邏輯分開.一個(gè)典型的DAO實(shí)現(xiàn)有下列幾個(gè)組件:
          1. 一個(gè)DAO工廠類;
          2. 一個(gè)DAO接口;
          3. 一個(gè)實(shí)現(xiàn)DAO接口的具體類;
          4. 數(shù)據(jù)傳遞對(duì)象(有些時(shí)候叫做值對(duì)象).

            閱讀全文
          posted @ 2008-10-09 15:11 java_蟈蟈 閱讀(1119) | 評(píng)論 (1)編輯 收藏

          安裝TOMCAT報(bào)如下錯(cuò)誤:
        1. Failed to install Tomcat6 service.     
        2. Check your settings and permissions Ignore and     
        3. continue anyway(not recommended)!    
        4. 原因:
          問(wèn)題是因?yàn)橹把b過(guò)tomcat安裝程序的問(wèn)題,卸載之后在服務(wù)中還保留有Apache Tomcat服務(wù)項(xiàng)的原因。
          只要?jiǎng)h除這個(gè)服務(wù)項(xiàng)就可以了!

          解決辦法:
          運(yùn)行cmd,用sc delete Tomcat5命令刪除就可以了  

          posted @ 2008-10-05 17:34 java_蟈蟈 閱讀(378) | 評(píng)論 (0)編輯 收藏

          最近一段時(shí)間一直在看設(shè)計(jì)模式,看面向?qū)ο?在JDON上面轉(zhuǎn),看別人的學(xué)習(xí)心得,看別人的學(xué)習(xí)經(jīng)驗(yàn),借以提高自己的內(nèi)功.""呵呵""."呵呵"二字已出,都不知道該往下說(shuō)什么好了.

          在現(xiàn)在的公司做著應(yīng)該干的\干的不順心的\千篇一律的\對(duì)自己的技術(shù)<內(nèi)功\外功>沒(méi)提高機(jī)會(huì)的工作,怎是一個(gè)郁悶了得.想想剛進(jìn)公司時(shí)的雀躍心情\雄心壯志,現(xiàn)在都不知道它們跑那里去了;處在一個(gè)松散的環(huán)境中,做著自己都感覺無(wú)聊的工作,想著自己所想的,學(xué)著自己該學(xué)的,談著無(wú)聊的話題,走在一條寂寞的小路上,無(wú)聊啊,郁悶啊,呵呵,看來(lái)我真的該走了,該走出去看看了......

          posted @ 2008-09-20 07:55 java_蟈蟈 閱讀(185) | 評(píng)論 (1)編輯 收藏


          解決方法如下:
          1.打開CMD. cmd
          2.查找端口號(hào)的PID netstat -a -o
          3.強(qiáng)行關(guān)閉 ntsd -c q -p PID(查詢出來(lái)的PID號(hào)碼)

          posted @ 2008-07-27 12:06 java_蟈蟈 閱讀(1656) | 評(píng)論 (3)編輯 收藏

               摘要: 如果你還不是一名程序員,你是否在為是否從事程序員工作而掙扎呢?
          如果你已經(jīng)是一名程序員,你是否在為程序員的前途而感到迷茫呢?
          如果是,我可以告訴你,做程序員是有前途的!   閱讀全文
          posted @ 2008-06-17 08:26 java_蟈蟈 閱讀(1390) | 評(píng)論 (2)編輯 收藏

          今天在測(cè)試將EXCEL里的數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫(kù)時(shí),語(yǔ)句能在查詢分析器里執(zhí)行,但不能在程序里執(zhí)行,報(bào)MSDTC不可用錯(cuò)誤,查了一下,將解決辦法貼出來(lái),供大家共享
            解決辦法:
            在windows控制面版-->管理工具-->服務(wù)-->Distributed   Transaction   Coordinator-->屬性-->啟動(dòng)
          posted @ 2008-06-13 17:29 java_蟈蟈 閱讀(598) | 評(píng)論 (0)編輯 收藏

               摘要: Spring聲明式事務(wù)讓我們從復(fù)雜的事務(wù)處理中得到解脫。使得我們?cè)僖矡o(wú)需要去處理獲得連接、關(guān)閉連接、事務(wù)提交和回滾等這些操作。再也無(wú)需要我們?cè)谂c事務(wù)相關(guān)的方法中處理大量的try…catch…finally代碼。
          我們?cè)谑褂肧pring聲明式事務(wù)時(shí),有一個(gè)非常重要的概念就是事務(wù)屬性。事務(wù)屬性通常由事務(wù)的傳播行為,事務(wù)的隔離級(jí)別,事務(wù)的超時(shí)值和事務(wù)只讀標(biāo)志組成。我們?cè)谶M(jìn)行事務(wù)劃分時(shí),需要進(jìn)行事務(wù)定義,也就是配置事務(wù)的屬性。
          Spring在TransactionDefinition接口中定義這些屬性,以供PlatfromTransactionManager使用, PlatfromTransactionManager是spring事務(wù)管理的核心接口。  閱讀全文
          posted @ 2008-05-05 21:52 java_蟈蟈 閱讀(280) | 評(píng)論 (0)編輯 收藏

               摘要: 使用spring的事務(wù)管理需要作這些事
          1,設(shè)置好事務(wù)源,比如DataSource,hibernate的session。如果有多個(gè)事務(wù)源要考慮他們之間是否有全局事務(wù),如果有,老老實(shí)實(shí)用jta,否則就需要自己寫一個(gè)manager了
          2,設(shè)置manager,根據(jù)你的事務(wù)源選擇對(duì)應(yīng)的PlatformTransactionManager
          3,選擇實(shí)現(xiàn)事物的方式,用template還是interceptor。用template代碼直觀點(diǎn),但是template所管轄的manager和你應(yīng)用代碼所用的事務(wù)源要一致。如果用interceptor千萬(wàn)注意,一定要調(diào)用interceptor那個(gè)bean,而不是原始的那個(gè)target。在壇子上我已經(jīng)看到至少有兩個(gè)朋友說(shuō)spring事物不起作用,從配置和代碼上看都正確,這時(shí)要好好查查,調(diào)用的bean是哪一個(gè)。
          4,這個(gè)是設(shè)計(jì)問(wèn)題了,推薦事務(wù)處于一個(gè)較高層次,比如service上的某個(gè)函數(shù),而底層的dao可以不考慮事務(wù),否則可能會(huì)出現(xiàn)事務(wù)嵌套,增加程序復(fù)雜度。   閱讀全文
          posted @ 2008-05-05 21:37 java_蟈蟈 閱讀(229) | 評(píng)論 (0)編輯 收藏

          錯(cuò)誤描述:....while loading persisted sessions: java.io.EOFException...
          分析:EOFException表示輸入過(guò)程中意外地到達(dá)文件尾或流尾的信號(hào),導(dǎo)致從session中獲取數(shù)據(jù)失敗。異常是tomcat本身的問(wèn)題,由于tomcat上次非正常關(guān)閉時(shí)有一些活動(dòng)session被持久化(表現(xiàn)為一些臨時(shí)文件),在重啟時(shí),tomcat嘗試去恢復(fù)這些session的持久化數(shù)據(jù)但又讀取失敗造成的。此異常不影響系統(tǒng)的使用。

          徹底解決辦法一下:將work下面的文件清空,主要是*.ser文件,或者只是刪除掉session.ser即可以解決。


           

          引自網(wǎng)絡(luò)

          posted @ 2008-04-24 07:39 java_蟈蟈 閱讀(2453) | 評(píng)論 (9)編輯 收藏

               摘要:   基于RBAC模型的權(quán)限管理系統(tǒng)的設(shè)計(jì)和實(shí)現(xiàn) 作者:裴輝東 梁云風(fēng)  來(lái)源:網(wǎng)絡(luò) 摘要:提出了基于RBAC模型的權(quán)限管理系統(tǒng)的設(shè)計(jì)和實(shí)現(xiàn)方案。介紹了采用的J2EE架構(gòu)的多層體系結(jié)構(gòu)設(shè)計(jì),闡述了基于角色的訪問(wèn)控制RBAC模型的設(shè)計(jì)思想,并討論了權(quán)限管理系統(tǒng)的核心面向?qū)ο笤O(shè)計(jì)模型,以及權(quán)限訪問(wèn)、權(quán)限控制和權(quán)限存儲(chǔ)機(jī)制等關(guān)鍵技術(shù)。  關(guān)鍵詞:權(quán)限管理系統(tǒng);角色;訪問(wèn)控制;R...  閱讀全文
          posted @ 2008-03-30 23:40 java_蟈蟈 閱讀(1223) | 評(píng)論 (0)編輯 收藏

               摘要: 1、在其他任何事物發(fā)生之前,將分配給對(duì)象的存儲(chǔ)空間初始化成二進(jìn)制零。

          2、調(diào)用基類構(gòu)造器。這個(gè)步驟會(huì)不斷的反復(fù)遞歸下去,首先是構(gòu)造這種層次結(jié)構(gòu)的根,然后是下一層導(dǎo)出類,等等。直到最低層的導(dǎo)出類。此時(shí),調(diào)用被重載的draw()方法(是的,是在調(diào)用RoundGlyph構(gòu)造器之前調(diào)用的),由于步驟(1)的緣故,我們此時(shí)會(huì)發(fā)現(xiàn)radius的值為0。

            閱讀全文
          posted @ 2007-11-13 17:09 java_蟈蟈 閱讀(298) | 評(píng)論 (0)編輯 收藏

               摘要: AOP = Proxy Pattern + Method Reflection + Aspect DSL + 自動(dòng)代碼生成

          Declarative Programming & DSL

          Aspect Oriented Programming(面向方面編程,簡(jiǎn)稱AOP)是一種Declarative Programming(聲明式編程)。
          Declarative Programming(聲明式編程)是和Imperative Programming(命令式編程)相對(duì)的概念。
          我們平時(shí)使用的編程語(yǔ)言,比如C++、Java、Ruby、Python等,都屬于Imperative Programming(命令式編程)。Imperative Programming(命令式編程)的意思是,程序員需要一步步寫清楚程序需要如何做什么(How to do What)。
            閱讀全文
          posted @ 2007-11-13 14:09 java_蟈蟈 閱讀(365) | 評(píng)論 (0)編輯 收藏

               摘要: AOP、OOP在字面上雖然非常類似,但卻是面向不同領(lǐng)域的兩種
          設(shè)計(jì)思想。OOP(面向?qū)ο缶幊蹋┽槍?duì)業(yè)務(wù)處理過(guò)程的實(shí)體及其屬性和行為進(jìn)行抽象封裝,
          以獲得更加清晰高效的邏輯單元?jiǎng)澐帧?
          而AOP則是針對(duì)業(yè)務(wù)處理過(guò)程中的切面進(jìn)行提取,它所面對(duì)的是處理過(guò)程中的某個(gè)步
          驟或階段,以獲得邏輯過(guò)程中各部分之間低耦合性的隔離效果。這兩種設(shè)計(jì)思想在目標(biāo)上有
          著本質(zhì)的差異。
            閱讀全文
          posted @ 2007-11-13 13:47 java_蟈蟈 閱讀(568) | 評(píng)論 (0)編輯 收藏

          請(qǐng)求加精Eclpise 的錯(cuò)誤myeclipse memory monitor pressing dirty regions 解決方法!

          我的eclipse加載的時(shí)候出現(xiàn)
          an internal error occurred during "myeclipse memory monitor"

          打開xml文檔的時(shí)候出現(xiàn)
          an internal error occurred during "pressing dirty regions"


          你們是不是也出現(xiàn)了這個(gè)錯(cuò)誤那
          很好解決

          只要把JDK 換成1.5.0_05 以上這個(gè)問(wèn)題就解決了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
          因?yàn)閖dk1.5.0不支持新的jar包

          Eclipse3.2 + Myeclipse5.0GA + Tomcat5.5.17 + j2sdk1.5 搭建J2EE開發(fā)環(huán)境
          一、安裝j2sdk1.5.0_07(默認(rèn)),設(shè)定環(huán)境變量。
          所以設(shè)定環(huán)境變量為:
          1. (新建)JAVA_HOME: C:\\Program Files\\Java\\jdk1.5.0_07
          2.(新建) CLASSPATH: .;C:\\Program Files\\Java\\jdk1.5.0_07\\lib\\dt.jar;C:\\Program Files\\Java\\jdk1.5.0_07\\lib\\tools.jar (注意:點(diǎn)號(hào)不能省略,表示當(dāng)前目錄)
          3. 編輯PATH的變量值,在后面加上 ;%JAVA_HOME%\\bin (注意:要有分號(hào)隔開)

          posted @ 2007-11-12 08:34 java_蟈蟈 閱讀(1366) | 評(píng)論 (0)編輯 收藏

               摘要: 經(jīng)常會(huì)問(wèn)到的面試題:String s = new String("abc");創(chuàng)建了幾個(gè)String Object?【如這里創(chuàng)建了多少對(duì)象? 和一道小小的面試題 】

          這個(gè)問(wèn)題比較簡(jiǎn)單,涉及的知識(shí)點(diǎn)包括:

          引用變量與對(duì)象的區(qū)別;
          字符串文字"abc"是一個(gè)String對(duì)象;
          文字池[pool of literal strings]和堆[heap]中的字符串對(duì)象。
            閱讀全文
          posted @ 2007-11-07 10:25 java_蟈蟈 閱讀(869) | 評(píng)論 (0)編輯 收藏

               摘要: 內(nèi)部類是指在一個(gè)外部類的內(nèi)部再定義一個(gè)類。內(nèi)部類作為外部類的一個(gè)成員,并且依附于外部類而存在的。內(nèi)部類可為靜態(tài),可用protected和private修飾(而外部類只能使用public和缺省的包訪問(wèn)權(quán)限)。內(nèi)部類主要有以下幾類:成員內(nèi)部類、局部?jī)?nèi)部類、靜態(tài)內(nèi)部類、匿名內(nèi)部類
            閱讀全文
          posted @ 2007-09-15 17:34 java_蟈蟈 閱讀(238) | 評(píng)論 (0)編輯 收藏

               摘要: JdbcTemplate將我們使用的JDBC的流程封裝起來(lái),包括了異常的捕捉、SQL的執(zhí)行、查詢結(jié)果的轉(zhuǎn)換等等。spring大量使用Template Method模式來(lái)封裝固定流程的動(dòng)作,XXXTemplate等類別都是基于這種方式的實(shí)現(xiàn)。
          除了大量使用Template Method來(lái)封裝一些底層的操作細(xì)節(jié),spring也大量使用callback方式類回調(diào)相關(guān)類別的方法以提供JDBC相關(guān)類別的功能,使傳統(tǒng)的JDBC的使用者也能清楚了解spring所提供的相關(guān)封裝類別方法的使用。  閱讀全文
          posted @ 2007-06-26 14:34 java_蟈蟈 閱讀(318) | 評(píng)論 (0)編輯 收藏

               摘要: 具體實(shí)現(xiàn):

          利用Filter的過(guò)濾功能把*.jsp過(guò)濾出來(lái),判斷是否存在對(duì)應(yīng)的.html文件,如果不存在對(duì)應(yīng)的.html文件,則將其內(nèi)容讀出寫入指定的.html文件,再跳轉(zhuǎn)到對(duì)應(yīng)的.html即可。如果存在對(duì)應(yīng)的.html文件,則直接跳轉(zhuǎn)到對(duì)應(yīng)的.html即可。
            閱讀全文
          posted @ 2007-05-30 16:26 java_蟈蟈 閱讀(5928) | 評(píng)論 (23)編輯 收藏

          前一段時(shí)間朋友用hibernate+mysql整了一個(gè)應(yīng)用,出現(xiàn)tomcat放一夜,mysql連接出現(xiàn)錯(cuò)誤的情況,具體的錯(cuò)誤信息忘記了。

          在網(wǎng)上查找一下,找到了這個(gè)帖子,還有就是這個(gè)了;原來(lái)Mysql在經(jīng)過(guò)8小時(shí)不使用后會(huì)自動(dòng)關(guān)閉已打開的連接,摘錄原文如下:

          5.4.

          I have a servlet/application that works fine for a day, and then stops working overnight

          MySQL closes connections after 8 hours of inactivity. You either need to use a connection pool that handles stale connections or use the "autoReconnect" parameter (see "Developing Applications with MySQL Connector/J").

          Also, you should be catching SQLExceptions in your application and dealing with them, rather than propagating them all the way until your application exits, this is just good programming practice. MySQL Connector/J will set the SQLState (see java.sql.SQLException.getSQLState() in your APIDOCS) to "08S01" when it encounters network-connectivity issues during the processing of a query. Your application code should then attempt to re-connect to MySQL at this point.

          現(xiàn)把具體方法貼出來(lái),以供大家共享.
          方法一:
                         設(shè)置你的MYSQL數(shù)據(jù)庫(kù):wait_timeout=24*60*60<秒>,把它的值設(shè)置大一點(diǎn),呵呵
           方法二:
                         配置Hibernate C3p0連接池,配置如下:
          <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
             <property name="c3p0.max_size">20</property>
             <property name="c3p0.min_size">5</property>
             <property name="c3p0.timeout">20</property>
             <property name="c3p0.max_statements">100</property>
             <property name="c3p0.idle_test_period">120</property>
             <property name="c3p0.acquire_increment">2</property>

          注意這里標(biāo)紅的部分,要設(shè)置c3p0.timeout的值小于MySql的wait_timeout的值,這樣才行,要不還會(huì)出現(xiàn)異常.

          這次是一個(gè)教訓(xùn),所以不論從穩(wěn)定還是性能的考慮,都應(yīng)該選擇相對(duì)更加成熟的連接池。

          posted @ 2007-05-23 10:52 java_蟈蟈 閱讀(955) | 評(píng)論 (0)編輯 收藏

               摘要: Lucene是apache組織的一個(gè)用java實(shí)現(xiàn)全文搜索引擎的開源項(xiàng)目。其功能非常的強(qiáng)大,api也很簡(jiǎn)單。總得來(lái)說(shuō)用Lucene來(lái)進(jìn)行建立和搜索與操作數(shù)據(jù)庫(kù)是差不多的,Document可以看作是數(shù)據(jù)庫(kù)的一行記錄,F(xiàn)ield可以看作是數(shù)據(jù)庫(kù)的字段。用lucene實(shí)現(xiàn)搜索引擎就像用JDBC實(shí)現(xiàn)連接數(shù)據(jù)庫(kù)一樣簡(jiǎn)單。   閱讀全文
          posted @ 2007-05-21 08:17 java_蟈蟈 閱讀(612) | 評(píng)論 (0)編輯 收藏

               摘要: struts-menu 權(quán)限控制

          在上一編的基礎(chǔ)上做如下工作即可:

          一、新建一個(gè)類,用于獲取允許顯示的菜單列表
          ......  閱讀全文
          posted @ 2007-05-18 08:45 java_蟈蟈 閱讀(492) | 評(píng)論 (0)編輯 收藏

               摘要: 采用Struts+Hibernate

          一、新建菜單表:表根據(jù)配置文件自己建吧,我這里就不寫了

          二、建立表對(duì)應(yīng)的Hibernate的配置文件及JAVABEAN




          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">





          閱讀全文
          posted @ 2007-05-17 18:54 java_蟈蟈 閱讀(2420) | 評(píng)論 (1)編輯 收藏

               摘要: 人民幣轉(zhuǎn)換...  閱讀全文
          posted @ 2007-04-22 10:46 java_蟈蟈 閱讀(412) | 評(píng)論 (0)編輯 收藏

          主站蜘蛛池模板: 信阳市| 安福县| 镶黄旗| 永寿县| 大化| 和顺县| 潍坊市| 太仆寺旗| 秦安县| 卓尼县| 陆良县| 广饶县| 临沂市| 尼勒克县| 巴马| 丹江口市| 汝州市| 兴安盟| 黄骅市| 阳新县| 漠河县| 泸定县| 克什克腾旗| 济源市| 贺兰县| 伊金霍洛旗| 建湖县| 米泉市| 镶黄旗| 姜堰市| 桦南县| 万安县| 宁阳县| 竹溪县| 始兴县| 高密市| 保定市| 稷山县| 郁南县| 马关县| 南城县|