<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    我的Blog我做主^_^

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

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      64 隨筆 :: 68 文章 :: 77 評論 :: 0 Trackbacks

    2007年3月21日 #

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

    原因是缺少.jar文件

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

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

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

    舉幾個這個方法實用的例子(注釋是輸出結果):

    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"
    是不是很方便,讓人動心啊?哈哈,還有更多的效果!

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

    產生格式化輸出的每個方法都需要格式字符串 和參數列表。格式字符串是一個 String,它可以包含固定文本以及一個或多個嵌入的格式說明符。請考慮以下示例:

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

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

    1.常規類型、字符類型和數值類型的格式說明符的語法如下:%[argument_index$][flags][width][.precision]conversion

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

    2.用來表示日期和時間類型的格式說明符的語法如下:
    %[argument_index$][flags][width]conversion

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


    3.與參數不對應的格式說明符的語法如下:
    %[flags][width]conversion

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

    轉換
    轉換可分為以下幾類:
    1. 常規 - 可應用于任何參數類型
    2. 字符 - 可應用于表示 Unicode 字符的基本類型:char、Character、byte、Byte、short 和 Short。當 Character.isValidCodePoint(int) 返回 true 時,可將此轉換應用于 int 和 Integer 類型
    3. 數值
          1. 整數 - 可應用于 Java 的整數類型:byte、Byte、short、Short、int、Integer、long、Long 和 BigInteger
          2. 浮點 - 可用于 Java 的浮點類型:float、Float、double、Double 和 BigDecimal
    4. 日期/時間 - 可應用于 Java 的、能夠對日期或時間進行編碼的類型:long、Long、Calendar 和 Date。
    5. 百分比 - 產生字面值 '%' ('\u0025')
    6. 行分隔符 - 產生特定于平臺的行分隔符

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

     

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

    任何未明確定義為轉換的字符都是非法字符,并且都被保留,以供將來擴展使用。

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

    以下轉換字符用來格式化時間:

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

    以下轉換字符用來格式化日期:

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

    以下轉換字符用于格式化常見的日期/時間組合。

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

    任何未明確定義為轉換的字符都是非法字符,并且都被保留,以供將來擴展使用。


    標志
    下表總結了受支持的標志。y 表示該標志受指示參數類型支持。

    標志 常規 字符 整數 浮點 日期/時間 說明
    '-' y     y     y     y     y 結果將是左對齊的。
    '#' y1     -     y3     y     -     結果應該使用依賴于轉換類型的替換形式
    '+' -     -     y4     y     -     結果總是包括一個符號
    '   ' -     -     y4     y     -     對于正值,結果中將包括一個前導空格
    '0' -     -     y     y     -     結果將用零來填充
    ',' -     -     y2     y5     -     結果將包括特定于語言環境的組分隔符
    '(' -     -     y4     y5     -     結果將是用圓括號括起來的負數

    1 取決于 Formattable 的定義。

    2 只適用于 'd' 轉換。

    3 只適用于 'o'、'x' 和 'X' 轉換。

    4 對 BigInteger 應用 'd'、'o'、'x' 和 'X' 轉換時,或者對 byte 及 Byte、short 及 Short、int 及 Integer、long 及 Long 分別應用 'd' 轉換時適用。

    5 只適用于 'e'、'E'、'f'、'g' 和 'G' 轉換。

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

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

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

    1.對整數進行格式化:%[index$][標識][最小寬度]轉換方式
            我們可以看到,格式化字符串由4部分組成,其中%[index$]的含義我們上面已經講過,[最小寬度]的含義也很好理解,就是最終該整數轉化的字符串最少包含多少位數字。我們來看看剩下2個部分的含義吧:

     


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

    轉換方式:
    d-十進制   o-八進制   x或X-十六進制        上面的說明過于枯燥,我們來看幾個具體的例子。需要特別注意的一點是:大部分標識字符可以同時使用。

            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));

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

    2.對浮點數進行格式化:%[index$][標識][最少寬度][.精度]轉換方式
            我們可以看到,浮點數的轉換多了一個“精度”選項,可以控制小數點后面的位數。

    標識:
    '-'    在最小寬度內左對齊,不可以與“用0填充”同時使用
    '+'    結果總是包括一個符號
    '  '    正值前加空格,負值前加負號
    '0'    結果將用零來填充
    ','    每3位數字之間用“,”分隔(只適用于fgG的轉換)
    '('    若參數是負數,則結果中不添加負號而是用圓括號把數字括起來(只適用于eEfgG的轉換)

    轉換方式:
    'e', 'E'  --  結果被格式化為用計算機科學記數法表示的十進制數
    'f'          --  結果被格式化為十進制普通表示方式
    'g', 'G'    --  根據具體情況,自動選擇用普通表示方式還是科學計數法方式
    'a', 'A'    --   結果被格式化為帶有效位數和指數的十六進制浮點數

    3.對字符進行格式化:
            對字符進行格式化是非常簡單的,c表示字符,標識中'-'表示左對齊,其他就沒什么了。

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

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

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

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

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

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

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

    當start虛擬器的時候,之后就彈出:SDL_app:emulator.exe 應用程序錯誤
    在網上查了些資料,先刪除AVD`,然后重新創建新的AVD,再重新運行項目竟然OK了,但關閉以后重新運行又報相同的錯誤。又在網上查了資料,查看任務管理器進程中應用是否還在運行,但刪除停止應用以后重新運行項目還是報相同的錯誤!
    解決方法:SD card size 不要設置,保準可以。(大家可以試試,我不敢保證可行)。

    新建一個AVD以后,第一次跑起來OK的,關閉以后重新跑,又有問題了,難道我每跑一次就重新建AVD?這個不是解決問題的根本辦法...很多人說,SD card size 不要設置,可以避免這個問題出現。


    本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/jincf2011/archive/2011/04/22/6342906.aspx

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

    Tomcat部署時報錯Could not copy all resources to...

    轉自:http://jiake0504.iteye.com/blog/253604

    在使用eclipse開發,發布應用的時候突然無法成功發布,提示  
     
    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服務并沒有啟動.上網搜索之后發現和大家范的是一個毛病,原來工程中我引了一個包,后來這個包被我給刪除了,但是因為已經發布過這個工程了,所以classpath中就有這個包名了,這樣發布的時候也會去找這個包但是已經不存在了,所以無copy,  
     
    解決辦法:在eclipse的工程中點擊右健選擇properties-->java build path中已經提示了xx.jar不存在,這樣就把這個jar信息從Libraries中刪除即可.  
     
    重新發布應用,成功!
    posted @ 2011-05-03 11:27 java_蟈蟈 閱讀(2296) | 評論 (0)編輯 收藏

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

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

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

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

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

    Spring的JDBCTemplate

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

    第一、使用Hibernate 的sql 查詢函數,將查詢結果對象轉為Entity對象。

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

    第三、選擇把Spring的JDBCTemplate作為一種很不錯的JDBC Utils來使用。

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

         AplicationContext定義:

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

    實際使用: 

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

    Tips1: jdbcTemplate有很多的ORM化回調操作將返回結果轉為對象列表,但很多時候還是需要返回ResultSet,Spring有提供一個類似ResultSet的 Spring SqlRowSet對象。

             

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


    Chapter 11. 使用JDBC進行數據訪問

    11.1. 簡介

    Spring JDBC抽象框架所帶來的價值將在以下幾個方面得以體現:(注:使用了Spring JDBC抽象框架之后,應用開發人員只需要完成斜體字部分的編碼工作。)

    1. 指定數據庫連接參數

    2. 打開數據庫連接

    3. 聲明SQL語句

    4. 預編譯并執行SQL語句

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

    6. 處理每一次遍歷操作

    7. 處理拋出的任何異常

    8. 處理事務

    9. 關閉數據庫連接

    Spring將替我們完成所有單調乏味的JDBC底層細節處理工作。

    11.1.1. Spring JDBC包結構

    Spring JDBC抽象框架由四個包構成:coredataSourceobject以及support

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

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

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

    最后,org.springframework.jdbc.support包提供了一些SQLException的轉換類以及相關的工具類。

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

    11.2. 利用JDBC核心類實現JDBC的基本操作和錯誤處理

    11.2.1. JdbcTemplate

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

    使用JdbcTemplate進行編碼只需要根據明確定義的一組契約來實現回調接口。PreparedStatementCreator回調接口通過給定的Connection創建一個PreparedStatement,包含SQL和任何相關的參數。CallableStatementCreateor實現同樣的處理,只不過它創建的是CallableStatement。RowCallbackHandler接口則從數據集的每一行中提取值。

    我們可以在一個service實現類中通過傳遞一個DataSource引用來完成JdbcTemplate的實例化,也可以在application context中配置一個JdbcTemplate bean,來供service使用。需要注意的是DataSource在application context總是配制成一個bean,第一種情況下,DataSource bean將傳遞給service,第二種情況下DataSource bean傳遞給JdbcTemplate bean。因為JdbcTemplate使用回調接口和SQLExceptionTranslator接口作為參數,所以一般情況下沒有必要通過繼承JdbcTemplate來定義其子類。

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

    11.2.2. NamedParameterJdbcTemplate

    NamedParameterJdbcTemplate類增加了在SQL語句中使用命名參數的支持。在此之前,在傳統的SQL語句中,參數都是用'?'占位符來表示的。 NamedParameterJdbcTemplate類內部封裝了一個普通的JdbcTemplate,并作為其代理來完成大部分工作。下面的內容主要針對NamedParameterJdbcTemplateJdbcTemplate的不同之處來加以說明,即如何在SQL語句中使用命名參數。

    通過下面的例子我們可以更好地了解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變量使用了命名參數占位符“first_name”,與其對應的值存在namedParameters變量中(類型為MapSqlParameterSource)。

    如果你喜歡的話,也可以使用基于Map風格的名值對將命名參數傳遞給NamedParameterJdbcTemplateNamedParameterJdbcTemplate實現了NamedParameterJdbcOperations接口,剩下的工作將由調用該接口的相應方法來完成,這里我們就不再贅述):

    // 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);
    }

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

    SqlParameterSource接口的另一個實現--BeanPropertySqlParameterSource為我們提供了更有趣的功能。該類包裝一個類似JavaBean的對象,所需要的命名參數值將由包裝對象提供,下面我們使用一個例子來更清楚地說明它的用法。

    // 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);
    }

    大家必須牢記一點:NamedParameterJdbcTemplate類內部包裝了一個標準的JdbcTemplate類。如果你需要訪問其內部的JdbcTemplate實例(比如訪問JdbcTemplate的一些方法)那么你需要使用getJdbcOperations()方法返回的JdbcOperations接口。(JdbcTemplate實現了JdbcOperations接口)。

    NamedParameterJdbcTemplate類是線程安全的,該類的最佳使用方式不是每次操作的時候實例化一個新的NamedParameterJdbcTemplate,而是針對每個DataSource只配置一個NamedParameterJdbcTemplate實例(比如在Spring IoC容器中使用Spring IoC來進行配置),然后在那些使用該類的DAO中共享該實例。

    11.2.3. SimpleJdbcTemplate

    [Note] Note

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

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

    SimpleJdbcTemplate 類利用Java 5的語法特性帶來的好處可以通過一個例子來說明。在下面的代碼片斷中我們首先使用標準的JdbcTemplate進行數據訪問,接下來使用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)});
    }

    下面是同一方法的另一種實現,惟一不同之處是我們使用了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接口

    為了從數據庫中取得數據,我們首先需要獲取一個數據庫連接。 Spring通過DataSource對象來完成這個工作。 DataSource是JDBC規范的一部分, 它被視為一個通用的數據庫連接工廠。通過使用DataSource, Container或Framework可以將連接池以及事務管理的細節從應用代碼中分離出來。 作為一個開發人員,在開發和測試產品的過程中,你可能需要知道連接數據庫的細節。 但在產品實施時,你不需要知道這些細節。通常數據庫管理員會幫你設置好數據源。

    在使用Spring JDBC時,你既可以通過JNDI獲得數據源,也可以自行配置數據源( 使用Spring提供的DataSource實現類)。使用后者可以更方便的脫離Web容器來進行單元測試。 這里我們將使用DriverManagerDataSource,不過DataSource有多種實現, 后面我們會講到。使用DriverManagerDataSource和你以前獲取一個JDBC連接 的做法沒什么兩樣。你首先必須指定JDBC驅動程序的全限定名,這樣DriverManager 才能加載JDBC驅動類,接著你必須提供一個url(因JDBC驅動而異,為了保證設置正確請參考相關JDBC驅動的文檔), 最后你必須提供一個用戶連接數據庫的用戶名和密碼。下面我們將通過一個例子來說明如何配置一個 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是一個接口,如果你需要在 SQLExceptionorg.springframework.dao.DataAccessException之間作轉換,那么必須實現該接口。

    轉換器類的實現可以采用一般通用的做法(比如使用JDBC的SQLState code),如果為了使轉換更準確,也可以進行定制(比如使用Oracle的error code)。

    SQLErrorCodeSQLExceptionTranslator是SQLExceptionTranslator的默認實現。 該實現使用指定數據庫廠商的error code,比采用SQLState更精確。 轉換過程基于一個JavaBean(類型為SQLErrorCodes)中的error code。 這個JavaBean由SQLErrorCodesFactory工廠類創建,其中的內容來自于 "sql-error-codes.xml"配置文件。該文件中的數據庫廠商代碼基于Database MetaData信息中的 DatabaseProductName,從而配合當前數據庫的使用。

     

    SQLErrorCodeSQLExceptionTranslator使用以下的匹配規則:

     

    • 首先檢查是否存在完成定制轉換的子類實現。通常SQLErrorCodeSQLExceptionTranslator 這個類可以作為一個具體類使用,不需要進行定制,那么這個規則將不適用。

    • 接著將SQLException的error code與錯誤代碼集中的error code進行匹配。 默認情況下錯誤代碼集將從SQLErrorCodesFactory取得。 錯誤代碼集來自classpath下的sql-error-codes.xml文件, 它們將與數據庫metadata信息中的database name進行映射。

    • 如果仍然無法匹配,最后將調用fallbackTranslator屬性的translate方法,SQLStateSQLExceptionTranslator類實例是默認的fallbackTranslator。

     

    SQLErrorCodeSQLExceptionTranslator可以采用下面的方式進行擴展:

    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;
    }
    }

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

    // 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();

    在上面的定制轉換器中,我們給它注入了一個數據源,因為我們仍然需要 使用默認的轉換器從sql-error-codes.xml中獲取錯誤代碼集。

    11.2.6. 執行SQL語句

    我們僅需要非常少的代碼就可以達到執行SQL語句的目的,一旦獲得一個 DataSource和一個JdbcTemplate, 我們就可以使用JdbcTemplate提供的豐富功能實現我們的操作。 下面的例子使用了極少的代碼完成創建一張表的工作。

    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. 執行查詢

    除了execute方法之外,JdbcTemplate還提供了大量的查詢方法。 在這些查詢方法中,有很大一部分是用來查詢單值的。比如返回一個匯總(count)結果 或者從返回行結果中取得指定列的值。這時我們可以使用queryForInt(..)queryForLong(..)或者queryForObject(..)方法。 queryForObject方法用來將返回的JDBC類型對象轉換成指定的Java對象,如果類型轉換失敗將拋出 InvalidDataAccessApiUsageException異常。 下面的例子演示了兩個查詢的用法,一個返回int值,另一個返回 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結果 的方法。List中的每一項對應查詢返回結果中的一行。其中最簡單的是queryForList方法, 該方法將返回一個List,該List中的每一條 記錄是一個Map對象,對應應數據庫中某一行;而該Map 中的每一項對應該數據庫行中的某一列值。下面的代碼片斷接著上面的例子演示了如何用該方法返回表中 所有記錄:

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

    返回的結果集類似下面這種形式:

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

    11.2.8. 更新數據庫

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

    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. 控制數據庫連接

    11.3.1. DataSourceUtils

    DataSourceUtils作為一個幫助類提供易用且強大的數據庫訪問能力, 我們可以使用該類提供的靜態方法從JNDI獲取數據庫連接以及在必要的時候關閉之。 它提供支持線程綁定的數據庫連接(比如使用DataSourceTransactionManager 的時候,將把數據庫連接綁定到當前的線程上)。

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

    11.3.2. SmartDataSource接口

    SmartDataSourceDataSource 接口的一個擴展,用來提供數據庫連接。使用該接口的類在指定的操作之后可以檢查是否需要關閉連接。 該接口在某些情況下非常有用,比如有些情況需要重用數據庫連接。

    11.3.3. AbstractDataSource

    AbstractDataSource是一個實現了DataSource 接口的abstract基類。它實現了DataSource接口的 一些無關痛癢的方法,如果你需要實現自己的DataSource,那么繼承 該類是個好主意。

    11.3.4. SingleConnectionDataSource

    SingleConnectionDataSourceSmartDataSource接口 的一個實現,其內部包裝了一個單連接。該連接在使用之后將不會關閉,很顯然它不能在多線程 的環境下使用。

    當客戶端代碼調用close方法的時候,如果它總是假設數據庫連接來自連接池(就像使用持久化工具時一樣), 你應該將suppressClose設置為true。 這樣,通過該類獲取的將是代理連接(禁止關閉)而不是原有的物理連接。 需要注意的是,我們不能把使用該類獲取的數據庫連接造型(cast)為Oracle Connection之類的本地數據庫連接。

    SingleConnectionDataSource主要在測試的時候使用。 它使得測試代碼很容易脫離應用服務器而在一個簡單的JNDI環境下運行。 與DriverManagerDataSource不同的是,它始終只會使用同一個數據庫連接, 從而避免每次建立物理連接的開銷。

    11.3.5. DriverManagerDataSource

    DriverManagerDataSource類實現了 SmartDataSource接口。在applicationContext.xml中可以使用 bean properties來設置JDBC Driver屬性,該類每次返回的都是一個新的連接。

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

    11.3.6. TransactionAwareDataSourceProxy

    TransactionAwareDataSourceProxy作為目標DataSource的一個代理, 在對目標DataSource包裝的同時,還增加了Spring的事務管理能力, 在這一點上,這個類的功能非常像J2EE服務器所提供的事務化的JNDI DataSource

    [Note] Note

    該類幾乎很少被用到,除非現有代碼在被調用的時候需要一個標準的 JDBC DataSource接口實現作為參數。 這種情況下,這個類可以使現有代碼參與Spring的事務管理。通常最好的做法是使用更高層的抽象 來對數據源進行管理,比如JdbcTemplateDataSourceUtils等等。

    如果需要更詳細的資料,請參考TransactionAwareDataSourceProxy JavaDoc 。

    11.3.7. DataSourceTransactionManager

    DataSourceTransactionManager類是 PlatformTransactionManager接口的一個實現,用于處理單JDBC數據源。 它將從指定DataSource取得的JDBC連接綁定到當前線程,因此它也支持了每個數據源對應到一個線程。

    我們推薦在應用代碼中使用DataSourceUtils.getConnection(DataSource)來獲取 JDBC連接,而不是使用J2EE標準的DataSource.getConnection。因為前者將拋出 unchecked的org.springframework.dao異常,而不是checked的 SQLException異常。Spring Framework中所有的類(比如 JdbcTemplate)都采用這種做法。如果不需要和這個 DataSourceTransactionManager類一起使用,DataSourceUtils 提供的功能跟一般的數據庫連接策略沒有什么兩樣,因此它可以在任何場景下使用。

    DataSourceTransactionManager類支持定制隔離級別,以及對SQL語句查詢超時的設定。 為了支持后者,應用代碼必須使用JdbcTemplate或者在每次創建SQL語句時調用 DataSourceUtils.applyTransactionTimeout方法。

    在使用單個數據源的情形下,你可以用DataSourceTransactionManager來替代JtaTransactionManager, 因為DataSourceTransactionManager不需要容器支持JTA。如果你使用DataSourceUtils.getConnection(DataSource)來獲取 JDBC連接,二者之間的切換只需要更改一些配置。最后需要注意的一點就是JtaTransactionManager不支持隔離級別的定制!

    11.4. 用Java對象來表達JDBC操作

    org.springframework.jdbc.object包下的類允許用戶以更加 面向對象的方式去訪問數據庫。比如說,用戶可以執行查詢并返回一個list, 該list作為一個結果集將把從數據庫中取出的列數據映射到業務對象的屬性上。 用戶也可以執行存儲過程,以及運行更新、刪除以及插入SQL語句。

    [Note] Note

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

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

    11.4.1. SqlQuery

    SqlQuery是一個可重用、線程安全的類,它封裝了一個SQL查詢。 其子類必須實現newResultReader()方法,該方法用來在遍歷 ResultSet的時候能使用一個類來保存結果。 我們很少需要直接使用SqlQuery,因為其子類 MappingSqlQuery作為一個更加易用的實現能夠將結果集中的行映射為Java對象。 SqlQuery還有另外兩個擴展分別是 MappingSqlQueryWithParametersUpdatableSqlQuery

    11.4.2. MappingSqlQuery

    MappingSqlQuery是一個可重用的查詢抽象類,其具體類必須實現 mapRow(ResultSet, int)抽象方法來將結果集中的每一行轉換成Java對象。

    SqlQuery的各種實現中, MappingSqlQuery是最常用也是最容易使用的一個。

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

    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;
    }
    }

    在上面的例子中,我們為用戶查詢提供了一個構造函數并為構造函數傳遞了一個 DataSource參數。在構造函數里面我們把 DataSource和一個用來返回查詢結果的SQL語句作為參數 調用父類的構造函數。SQL語句將被用于生成一個PreparedStatement對象, 因此它可以包含占位符來傳遞參數。而每一個SQL語句的參數必須通過調用 declareParameter方法來進行聲明,該方法需要一個 SqlParameter(封裝了一個字段名字和一個 java.sql.Types中定義的JDBC類型)對象作為參數。 所有參數定義完之后,我們調用compile()方法來對SQL語句進行預編譯。

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

    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方法通過傳遞惟一參數id來返回一個客戶對象。 該方法內部在創建CustomerMappingQuery實例之后, 我們創建了一個對象數組用來包含要傳遞的查詢參數。這里我們只有唯一的一個 Integer參數。執行CustomerMappingQuery的 execute方法之后,我們得到了一個List,該List中包含一個 Customer對象,如果有對象滿足查詢條件的話。

    11.4.3. SqlUpdate

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

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

    SqlUpdate是一個具體的類。通過在SQL語句中定義參數,這個類可以支持 不同的更新方法,我們一般不需要通過繼承來實現定制。

    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類是一個抽象基類,它是對RDBMS存儲過程的一種抽象。 該類提供了多種execute(..)方法,不過這些方法的訪問類型都是protected的。

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

    下面的程序演示了如何調用Oracle中的sysdate()函數。 這里我們創建了一個繼承StoredProcedure的子類,雖然它沒有輸入參數, 但是我必須通過使用SqlOutParameter來聲明一個日期類型的輸出參數。 execute()方法將返回一個map,map中的每個entry是一個用參數名作key, 以輸出參數為value的名值對。

    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的另一個例子,它使用了兩個Oracle游標類型的輸出參數。

    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構造函數中 declareParameter(..)SqlOutParameter參數, 該參數使用了RowMapper接口的實現。 這是一種非常方便而強大的重用方式。 下面我們來看一下RowMapper的兩個具體實現。

    首先是TitleMapper類,它簡單的把ResultSet中的每一行映射為一個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;
    }
    }

    另一個是GenreMapper類,也是非常簡單的將ResultSet中的每一行映射為一個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"));
    }
    }

    如果你需要給存儲過程傳輸入參數(這些輸入參數是在RDBMS存儲過程中定義好了的), 則需要提供一個指定類型的execute(..)方法, 該方法將調用基類的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操作類封裝了一個SQL“函數”包裝器(wrapper), 該包裝器適用于查詢并返回一個單行結果集。默認返回的是一個int值, 不過我們可以采用類似JdbcTemplate中的queryForXxx 做法自己實現來返回其它類型。SqlFunction優勢在于我們不必創建 JdbcTemplate,這些它都在內部替我們做了。

    該類的主要用途是調用SQL函數來返回一個單值的結果集,比如類似“select user()”、 “select sysdate from dual”的查詢。如果需要調用更復雜的存儲函數, 可以使用StoredProcedureSqlCall

    SqlFunction是一個具體類,通常我們不需要它的子類。 其用法是創建該類的實例,然后聲明SQL語句以及參數就可以調用相關的run方法去多次執行函數。 下面的例子用來返回指定表的記錄行數:

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

     因前段時間碰到java.lang.OutOfMemoryError: PermGen space問題,想到檢控TOMCAT及調優問題,從網上搜到這個工具,一開始配置了N久后也未配起來,后來偶然間配置好了,隨把過程寫到此,以便共享

    測試:tomcat5+jprofiler_windows_5_1_4 它的注冊碼可到官網上注冊一個,免費試用,當然是有期限的

    有的時候Tomcat跑Web應用會慢慢死掉,CPU 100%占用。一般情況下是程序哪里出了問題,慢慢的DEBUG,幾乎翻遍所有的代碼,是不是很累?這里介紹一下JProfiler,比較優秀的性能監控和分析工具。
    JProfiler我用的是4.3.3版本,他是收費的,不過google上面很多注冊碼可供使用。
    安裝的時候會提示一些比如尋找JVM等過程,這里就不多說了。安裝完JProfiler,運行,出現如下界面:

    由于我們是要創建對本地tomcat的監控,選擇an application server,locally or remotely.
    在接下來的窗口中,選擇tomcat及版本,

    下一步,選擇本地:

    下一步,選擇啟動批處理文件


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

    下一步,選擇JVM類型:

    接著選擇JProfiler的監聽端口:

    接著,選擇直接啟動:

    下面會有一個很重要的提示,可能很多人在這里都沒有注意而總是配置不好JProfiler:

    上面標紅的配置好后,這下面的根本不用配置就可以跑起來了

    第一,需要把
    -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:\Program Files\jprofiler4\bin\windows放在PATH中。

    我是使用.bat來啟動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
    但是這樣啟動會有問題,因為其中路徑包含了空格,
    所以拷貝comfig.xml和agent.jar到一個新的路徑下面,比如:
    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就是剛才設置的jprofiler監控端口。
    設置完這些,通過startup.bat啟動tomcat,然后

    點OK

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

    今日整到此處,特將網上搜刮來的信息貼于此,以供大家共享之

    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>

    描述:
    事件觸發的時候彈出一個有確定和取消的對話框,確定則離開頁面,取消則繼續待在本頁。
    handler可以設一個返回值作為該對話框的顯示文本。

    觸發于:

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

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

    平臺支持:
    IE4+/Win, Mozilla 1.7a+, Netscape 7.2+, Firefox0.9+


     

    標簽只有onload\onunload\onbeforeunload事件,而沒有onclose事件。不管頁面是關閉還是刷新都會執行onunload事件。如何捕捉到頁面關閉呢?
    頁面加載時只執行onload
    頁面關閉時只執行onunload
    頁面刷新時先執行onbeforeunload,然后onunload,最后onload。這樣我們可以在onbeforeunload中加一個標記,在onunload中判斷該標記,即可達到判斷頁面是否真的關閉了。
    posted @ 2008-12-08 20:00 java_蟈蟈 閱讀(7867) | 評論 (2)編輯 收藏

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

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

    安裝TOMCAT報如下錯誤:
  • Failed to install Tomcat6 service.     
  • Check your settings and permissions Ignore and     
  • continue anyway(not recommended)!    
  • 原因:
    問題是因為之前裝過tomcat安裝程序的問題,卸載之后在服務中還保留有Apache Tomcat服務項的原因。
    只要刪除這個服務項就可以了!

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

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

    最近一段時間一直在看設計模式,看面向對象,在JDON上面轉,看別人的學習心得,看別人的學習經驗,借以提高自己的內功.""呵呵""."呵呵"二字已出,都不知道該往下說什么好了.

    在現在的公司做著應該干的\干的不順心的\千篇一律的\對自己的技術<內功\外功>沒提高機會的工作,怎是一個郁悶了得.想想剛進公司時的雀躍心情\雄心壯志,現在都不知道它們跑那里去了;處在一個松散的環境中,做著自己都感覺無聊的工作,想著自己所想的,學著自己該學的,談著無聊的話題,走在一條寂寞的小路上,無聊啊,郁悶啊,呵呵,看來我真的該走了,該走出去看看了......

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


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

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

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

    今天在測試將EXCEL里的數據導入數據庫時,語句能在查詢分析器里執行,但不能在程序里執行,報MSDTC不可用錯誤,查了一下,將解決辦法貼出來,供大家共享
      解決辦法:
      在windows控制面版-->管理工具-->服務-->Distributed   Transaction   Coordinator-->屬性-->啟動
    posted @ 2008-06-13 17:29 java_蟈蟈 閱讀(596) | 評論 (0)編輯 收藏

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

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

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

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


     

    引自網絡

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

         摘要:   基于RBAC模型的權限管理系統的設計和實現 作者:裴輝東 梁云風  來源:網絡 摘要:提出了基于RBAC模型的權限管理系統的設計和實現方案。介紹了采用的J2EE架構的多層體系結構設計,闡述了基于角色的訪問控制RBAC模型的設計思想,并討論了權限管理系統的核心面向對象設計模型,以及權限訪問、權限控制和權限存儲機制等關鍵技術。  關鍵詞:權限管理系統;角色;訪問控制;R...  閱讀全文
    posted @ 2008-03-30 23:40 java_蟈蟈 閱讀(1222) | 評論 (0)編輯 收藏

         摘要: 1、在其他任何事物發生之前,將分配給對象的存儲空間初始化成二進制零。

    2、調用基類構造器。這個步驟會不斷的反復遞歸下去,首先是構造這種層次結構的根,然后是下一層導出類,等等。直到最低層的導出類。此時,調用被重載的draw()方法(是的,是在調用RoundGlyph構造器之前調用的),由于步驟(1)的緣故,我們此時會發現radius的值為0。

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

         摘要: AOP = Proxy Pattern + Method Reflection + Aspect DSL + 自動代碼生成

    Declarative Programming & DSL

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

         摘要: AOP、OOP在字面上雖然非常類似,但卻是面向不同領域的兩種
    設計思想。OOP(面向對象編程)針對業務處理過程的實體及其屬性和行為進行抽象封裝,
    以獲得更加清晰高效的邏輯單元劃分。
    而AOP則是針對業務處理過程中的切面進行提取,它所面對的是處理過程中的某個步
    驟或階段,以獲得邏輯過程中各部分之間低耦合性的隔離效果。這兩種設計思想在目標上有
    著本質的差異。
      閱讀全文
    posted @ 2007-11-13 13:47 java_蟈蟈 閱讀(566) | 評論 (0)編輯 收藏

    請求加精Eclpise 的錯誤myeclipse memory monitor pressing dirty regions 解決方法!

    我的eclipse加載的時候出現
    an internal error occurred during "myeclipse memory monitor"

    打開xml文檔的時候出現
    an internal error occurred during "pressing dirty regions"


    你們是不是也出現了這個錯誤那
    很好解決

    只要把JDK 換成1.5.0_05 以上這個問題就解決了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    因為jdk1.5.0不支持新的jar包

    Eclipse3.2 + Myeclipse5.0GA + Tomcat5.5.17 + j2sdk1.5 搭建J2EE開發環境
    一、安裝j2sdk1.5.0_07(默認),設定環境變量。
    所以設定環境變量為:
    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 (注意:點號不能省略,表示當前目錄)
    3. 編輯PATH的變量值,在后面加上 ;%JAVA_HOME%\\bin (注意:要有分號隔開)

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

         摘要: 經常會問到的面試題:String s = new String("abc");創建了幾個String Object?【如這里創建了多少對象? 和一道小小的面試題 】

    這個問題比較簡單,涉及的知識點包括:

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

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

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

         摘要: 具體實現:

    利用Filter的過濾功能把*.jsp過濾出來,判斷是否存在對應的.html文件,如果不存在對應的.html文件,則將其內容讀出寫入指定的.html文件,再跳轉到對應的.html即可。如果存在對應的.html文件,則直接跳轉到對應的.html即可。
      閱讀全文
    posted @ 2007-05-30 16:26 java_蟈蟈 閱讀(5927) | 評論 (23)編輯 收藏

    前一段時間朋友用hibernate+mysql整了一個應用,出現tomcat放一夜,mysql連接出現錯誤的情況,具體的錯誤信息忘記了。

    在網上查找一下,找到了這個帖子,還有就是這個了;原來Mysql在經過8小時不使用后會自動關閉已打開的連接,摘錄原文如下:

    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.

    現把具體方法貼出來,以供大家共享.
    方法一:
                   設置你的MYSQL數據庫:wait_timeout=24*60*60<秒>,把它的值設置大一點,呵呵
     方法二:
                   配置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>

    注意這里標紅的部分,要設置c3p0.timeout的值小于MySql的wait_timeout的值,這樣才行,要不還會出現異常.

    這次是一個教訓,所以不論從穩定還是性能的考慮,都應該選擇相對更加成熟的連接池。

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

         摘要: Lucene是apache組織的一個用java實現全文搜索引擎的開源項目。其功能非常的強大,api也很簡單。總得來說用Lucene來進行建立和搜索與操作數據庫是差不多的,Document可以看作是數據庫的一行記錄,Field可以看作是數據庫的字段。用lucene實現搜索引擎就像用JDBC實現連接數據庫一樣簡單。   閱讀全文
    posted @ 2007-05-21 08:17 java_蟈蟈 閱讀(611) | 評論 (0)編輯 收藏

         摘要: struts-menu 權限控制

    在上一編的基礎上做如下工作即可:

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

         摘要: 采用Struts+Hibernate

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

    二、建立表對應的Hibernate的配置文件及JAVABEAN




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





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

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

         摘要:  1. Programming Guide 1.1. Prototype是什么? 1.2. 關聯文章 1.3. 通用性方法 1.3.1. 使用 $()方法 1.3.2. 使用$F()方法 1.3.3. 使用$A()方法 1.3.4. 使用$H()方法 1.3.5. 使用$R()方法 1.3.6. 使用Try.these()方法 1.4. Ajax 對...  閱讀全文
    posted @ 2007-04-17 17:17 java_蟈蟈 閱讀(246) | 評論 (0)編輯 收藏

    在寫JSP程序的時候,如果程序中調用了response.getOutputStream()去向客戶端輸出文件等數據流,容器就會拋出這樣的異常:
    Java.lang.IllegalStateException: getOutputStream() has already been called for this response
            at org.apache.catalina.connector.Response.getWriter(Response.java:596)
            at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:186)
      產生這樣的異常原因:是web容器生成的servlet代碼中有out.write(""),這個和JSP中調用的response.getOutputStream()產生沖突.即Servlet規范說明,不能既調用response.getOutputStream(),又調用response.getWriter(),無論先調用哪一個,在調用第二個時候應會拋出IllegalStateException,因為在jsp中,out變量實際上是通過response.getWriter得到的,你的程序中既用了response.getOutputStream,又用了out變量,故出現以上錯誤。
      解決方案:在程序的最后添加:
    out.clear();
    out = pageContext.pushBody();
    就可以了。

    http://blog.erp100.com/html/39/3639-1547.html
    posted @ 2007-04-13 11:54 java_蟈蟈 閱讀(319) | 評論 (0)編輯 收藏

         摘要: 詳細信息...  閱讀全文
    posted @ 2007-04-05 19:02 java_蟈蟈 閱讀(303) | 評論 (0)編輯 收藏

         摘要: A、 簡單工廠模式Simple Factory



    簡單工廠模式就是由一個工廠類根據傳入的參量決定創建出哪一種產品類的實例。

    實例:

    商店-----------à銷貨員[工廠] -------賣----à水果[抽象產品]<蘋果[產品一]、梨[產品二]、草莓[產品三]>

    用戶告訴銷貨員水果的名稱,銷貨員通過水果名稱找到相應的水果;
      閱讀全文
    posted @ 2007-04-05 00:32 java_蟈蟈 閱讀(244) | 評論 (0)編輯 收藏

         摘要: 數據庫被置疑的解決辦法 一:

    在MS SQLSERVER中一直有這樣的問題,SQLSERVER的狀態"置疑",我們先來分析一下SQLSERVER數據庫"置疑"的原因:
    1.錯誤的刪除日志;
    2.硬件(HD)損壞,造成日志和數據文件寫錯誤;
    3.硬盤的空間不夠,比如日志文件過大;  閱讀全文
    posted @ 2007-03-31 16:04 java_蟈蟈 閱讀(7765) | 評論 (0)編輯 收藏

         摘要: 請大家談談,拿到這樣一個系統,是怎么進行分析和設計的?怎么處理類與類之間的層次,和通信。

    比如把新聞發布系統分為話題:注冊登陸、新聞發布、權限管理。

    在“注冊登陸”系統中怎么分析?其中有表單類,那么新填寫的注冊、已經填寫的注冊、已經履行的注冊,這些是當成表單類的子類還是表單類的對象,該怎么處理和設計?   閱讀全文
    posted @ 2007-03-24 11:44 java_蟈蟈 閱讀(1238) | 評論 (0)編輯 收藏

         摘要: J2EE網站經驗共享!
    網站包括 商家博客,個人博客,論壇,新聞等

    設計采用了MVC模式,具體調用的時候采用了命令模式
    數據操作層Model中,例如;BlockDAO,TopicDAO,ResponseDAO,UserDAO等。
    里面封裝了一個對象所有的數據操作

    視圖/傳輸層 View 例如BlockDTO,TopicDTO等,主要是對象的屬性
    jsp用它來顯示,dao用它作為DTO最后就是控制層 Controll 控制層的類都繼承了Service接口
    里面有一個方法

    下面說說安全架構:
    網站采用J2EE的身份認證系統,通過對不同路徑的權限限制來做到不用角色具有不同操作捐獻
    例如:bbs/user/* 下主要是普通用戶的操作權限
    想新建帖子的時候,請求地址是 bbs/user/insertTopic.jsp

    bbs/blockAdmin/*主要是板塊管理員的權限
    bbs/bbsAdmin/* 下是論壇管理員的權限
    bbs/sysAdm  閱讀全文
    posted @ 2007-03-24 11:16 java_蟈蟈 閱讀(421) | 評論 (0)編輯 收藏

         摘要: 開始想在服務器上整一下呢,仔細一看不行,附Tomcat過濾IP方法:
    限制ip,限制主機訪問:
    如果想禁止指定的ip或者主機名來拒絕某些機器訪問,或者指定某些機器來訪問。
    也支持分別按Engine, Host, or Context,進行以下配置:
    ...
    allow="*.mycompany.com,www.yourcompany.com"/>
    deny="192.168.1.*"/>

    參考:
    http://jakarta.apache.org/tomcat/tomcat-5.0-doc/config/context.html
    沒轍,繼續... <  閱讀全文
    posted @ 2007-03-23 14:48 java_蟈蟈 閱讀(1478) | 評論 (4)編輯 收藏

         摘要: session詳解:
    1、一個瀏覽器窗口打開到關閉這個期間
    2、一系列動作、一次連接
    3、當session一詞與網絡協議相關聯時;“面向連接”和/或“保持狀態”
    4、到了web服務器蓬勃發展的時代;指一類用來在客戶端與服務器之間保持狀態的解決方案
    5、有時候session也用來指這種解決方案的存儲結構,如“把xxx保存在session 里
    6、在某種特定語言的語境下,session也被用來指代該語言的解決方案

    看完整篇文章后,不僅讓我想起了"單點登錄"問題;http://www.tkk7.com/wyz191/archive/2007/02/01/97291.html  閱讀全文
    posted @ 2007-03-21 08:36 java_蟈蟈 閱讀(231) | 評論 (0)編輯 收藏

    主站蜘蛛池模板: 亚洲国产成人VA在线观看| 亚洲AV无码精品无码麻豆| 和老外3p爽粗大免费视频| 亚洲精品成人无码中文毛片不卡| 99免费观看视频| 亚洲日韩AV一区二区三区中文| 亚洲国语在线视频手机在线| 久久久久久国产精品免费免费 | 日韩免费观看视频| 一级全免费视频播放| 亚洲欧洲精品在线| 亚洲第一区在线观看| 91精品啪在线观看国产线免费| 看亚洲a级一级毛片| 亚洲视频在线观看| 日本高清免费观看| 亚洲av日韩专区在线观看| 亚洲AV无码一区二区二三区入口 | a毛片免费全部在线播放**| 亚洲综合色7777情网站777| 亚洲人成影院在线观看| 黄页网站免费在线观看| 在线观看人成视频免费无遮挡| 亚洲综合成人婷婷五月网址| 国产亚洲人成网站观看| 国产成人啪精品视频免费网| 中文字幕在线免费| 中文字幕免费视频精品一| 亚洲国产一成人久久精品| 在线免费观看中文字幕| 99热这里只有精品免费播放| 一级毛片免费在线播放| 在线aⅴ亚洲中文字幕| 久久精品国产亚洲AV香蕉| 亚洲一级片内射网站在线观看| 成人五级毛片免费播放| 18禁男女爽爽爽午夜网站免费| 国产一级婬片A视频免费观看| 欧洲亚洲综合一区二区三区 | 亚洲av伊人久久综合密臀性色| 国产成人免费a在线资源|