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

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

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

    隨筆 - 42, 文章 - 1, 評論 - 0, 引用 - 0
    數據加載中……

    2011年12月28日

    Jquery操作select

         摘要: 以下是操作 下拉列表的常用功能:1.獲取列表項中候選項的數目。2.獲得選中項的索引值。3.獲得當前選中項的值4.設定選擇值5.設定選擇項 1 //得到select項的個數     2 jQuery.fn.size = function(){     ...  閱讀全文

    posted @ 2012-04-05 14:00 段旭 閱讀(1144) | 評論 (0)編輯 收藏

    Oracle全角変換

    SELECT 

                   UTL_I18N.TRANSLITERATE (TO_MULTI_BYTE(NAME), 'KANA_HIRAGANA') NAME--半角カタカナ?英數字-->全角ひらかな
                 , UTL_I18N.TRANSLITERATE (TO_MULTI_BYTE(KANA), 'KANA_FWKATAKANA') KANA--半角カタカナ-->全角カタカナ
                 , UTL_I18N.TRANSLITERATE (TO_MULTI_BYTE(SEIKINAME), 'KANA_HIRAGANA') SEIKINAME--半角カタカナ-->全角ひらかな
                 , UTL_I18N.TRANSLITERATE (TO_MULTI_BYTE(SEIKIKANA), 'HIRAGANA_HWKATAKANA') SEIKIKANA --全角ひらかな?カタカナ-->半角タカ
                 , UTL_I18N.TRANSLITERATE (TO_MULTI_BYTE(ZYUSHO), 'KANA_HIRAGANA') ZYUSHO--半角カタカナ-->全角ひらかな

    posted @ 2012-03-27 18:52 段旭 閱讀(638) | 評論 (0)編輯 收藏

    mysql 取整函數

    1.ceil () /ceiling() 向上取整

        ex: ceil(1.2) = 2

     2.floor () 向下取整

         ex: floor(1.2) = 1

     3.round() 四舍五入

    posted @ 2012-03-07 16:32 段旭 閱讀(2372) | 評論 (0)編輯 收藏

    mysql 日期

    這里是一個使用日期函數的例子。下面的查詢選擇了所有記錄,其date_col的值是在最后30天以內:

    mysql> SELECT something FROM table 
    WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30;

    DAYOFWEEK(date) 
    返回日期date的星期索引(1=星期天,2=星期一, ……7=星期六)。這些索引值對應于ODBC標準。 
    mysql> select DAYOFWEEK('1998-02-03'); 
    -> 3

    WEEKDAY(date) 
    返回date的星期索引(0=星期一,1=星期二, ……6= 星期天)。 
    mysql> select WEEKDAY('1997-10-04 22:23:00'); 
    -> 5 
    mysql> select WEEKDAY('1997-11-05'); 
    -> 2

    DAYOFMONTH(date) 
    返回date的月份中日期,在1到31范圍內。 
    mysql> select DAYOFMONTH('1998-02-03'); 
    -> 3

    DAYOFYEAR(date) 
    返回date在一年中的日數, 在1到366范圍內。 
    mysql> select DAYOFYEAR('1998-02-03'); 
    -> 34

    MONTH(date) 
    返回date的月份,范圍1到12。 
    mysql> select MONTH('1998-02-03'); 
    -> 2

    DAYNAME(date) 
    返回date的星期名字。 
    mysql> select DAYNAME("1998-02-05"); 
    -> 'Thursday'

    MONTHNAME(date) 
    返回date的月份名字。 
    mysql> select MONTHNAME("1998-02-05"); 
    -> 'February'

    QUARTER(date) 
    返回date一年中的季度,范圍1到4。 
    mysql> select QUARTER('98-04-01'); 
    -> 2

    WEEK(date)

    WEEK(date,first) 
    對于星期天是一周的第一天的地方,有一個單個參數,返回date的周數,范圍在0到52。2個參數形式WEEK()允許 
    你指定星期是否開始于星期天或星期一。如果第二個參數是0,星期從星期天開始,如果第二個參數是1, 
    從星期一開始。 
    mysql> select WEEK('1998-02-20'); 
    -> 7 
    mysql> select WEEK('1998-02-20',0); 
    -> 7 
    mysql> select WEEK('1998-02-20',1); 
    -> 8

    YEAR(date) 
    返回date的年份,范圍在1000到9999。 
    mysql> select YEAR('98-02-03'); 
    -> 1998

    HOUR(time) 
    返回time的小時,范圍是0到23。 
    mysql> select HOUR('10:05:03'); 
    -> 10

    MINUTE(time) 
    返回time的分鐘,范圍是0到59。 
    mysql> select MINUTE('98-02-03 10:05:03'); 
    -> 5

    SECOND(time) 
    回來time的秒數,范圍是0到59。 
    mysql> select SECOND('10:05:03'); 
    -> 3

    PERIOD_ADD(P,N) 
    增加N個月到階段P(以格式YYMM或YYYYMM)。以格式YYYYMM返回值。注意階段參數P不是日期值。 
    mysql> select PERIOD_ADD(9801,2); 
    -> 199803

    PERIOD_DIFF(P1,P2) 
    返回在時期P1和P2之間月數,P1和P2應該以格式YYMM或YYYYMM。注意,時期參數P1和P2不是日期值。 
    mysql> select PERIOD_DIFF(9802,199703); 
    -> 11

    DATE_ADD(date,INTERVAL expr type)

    DATE_SUB(date,INTERVAL expr type)

    ADDDATE(date,INTERVAL expr type)

    SUBDATE(date,INTERVAL expr type) 
    這些功能執行日期運算。對于MySQL 3.22,他們是新的。ADDDATE()和SUBDATE()是DATE_ADD()和DATE_SUB()的同義詞。 
    在MySQL 3.23中,你可以使用+和-而不是DATE_ADD()和DATE_SUB()。(見例子)date是一個指定開始日期的 
    DATETIME或DATE值,expr是指定加到開始日期或從開始日期減去的間隔值一個表達式,expr是一個字符串;它可以以 
    一個“-”開始表示負間隔。type是一個關鍵詞,指明表達式應該如何被解釋。EXTRACT(type FROM date)函數從日期 
    中返回“type”間隔。下表顯示了type和expr參數怎樣被關聯: type值 含義 期望的expr格式 
    SECOND 秒 SECONDS 
    MINUTE 分鐘 MINUTES 
    HOUR 時間 HOURS 
    DAY 天 DAYS 
    MONTH 月 MONTHS 
    YEAR 年 YEARS 
    MINUTE_SECOND 分鐘和秒 "MINUTES:SECONDS" 
    HOUR_MINUTE 小時和分鐘 "HOURS:MINUTES" 
    DAY_HOUR 天和小時 "DAYS HOURS" 
    YEAR_MONTH 年和月 "YEARS-MONTHS" 
    HOUR_SECOND 小時, 分鐘, "HOURS:MINUTES:SECONDS" 
    DAY_MINUTE 天, 小時, 分鐘 "DAYS HOURS:MINUTES" 
    DAY_SECOND 天, 小時, 分鐘, 秒 "DAYS HOURS:MINUTES:SECONDS"

    MySQL在expr格式中允許任何標點分隔符。表示顯示的是建議的分隔符。如果date參數是一個DATE值并且你的計算僅僅 
    包含YEAR、MONTH和DAY部分(即,沒有時間部分),結果是一個DATE值。否則結果是一個DATETIME值。

    mysql> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND; 
    -> 1998-01-01 00:00:00 
    mysql> SELECT INTERVAL 1 DAY + "1997-12-31"; 
    -> 1998-01-01 
    mysql> SELECT "1998-01-01" - INTERVAL 1 SECOND; 
    -> 1997-12-31 23:59:59 
    mysql> SELECT DATE_ADD("1997-12-31 23:59:59", 
    INTERVAL 1 SECOND); 
    -> 1998-01-01 00:00:00 
    mysql> SELECT DATE_ADD("1997-12-31 23:59:59", 
    INTERVAL 1 DAY); 
    -> 1998-01-01 23:59:59 
    mysql> SELECT DATE_ADD("1997-12-31 23:59:59", 
    INTERVAL "1:1" MINUTE_SECOND); 
    -> 1998-01-01 00:01:00 
    mysql> SELECT DATE_SUB("1998-01-01 00:00:00", 
    INTERVAL "1 1:1:1" DAY_SECOND); 
    -> 1997-12-30 22:58:59 
    mysql> SELECT DATE_ADD("1998-01-01 00:00:00", 
    INTERVAL "-1 10" DAY_HOUR); 
    -> 1997-12-30 14:00:00 
    mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY); 
    -> 1997-12-02 
    mysql> SELECT EXTRACT(YEAR FROM "1999-07-02"); 
    -> 1999 
    mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03"); 
    -> 199907 
    mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03"); 
    -> 20102

    如果你指定太短的間隔值(不包括type關鍵詞期望的間隔部分),MySQL假設你省掉了間隔值的最左面部分。例如, 
    如果你指定一個type是DAY_SECOND,值expr被希望有天、小時、分鐘和秒部分。如果你象"1:10"這樣指定值, 
    MySQL假設日子和小時部分是丟失的并且值代表分鐘和秒。換句話說,"1:10" DAY_SECOND以它等價于"1:10" MINUTE_SECOND 
    的方式解釋,這對那MySQL解釋TIME值表示經過的時間而非作為一天的時間的方式有二義性。如果你使用確實不正確的日期, 
    結果是NULL。如果你增加MONTH、YEAR_MONTH或YEAR并且結果日期大于新月份的最大值天數,日子在新月用最大的天調整。

    mysql> select DATE_ADD('1998-01-30', Interval 1 month); 
    -> 1998-02-28

    注意,從前面的例子中詞INTERVAL和type關鍵詞不是區分大小寫的。 
    TO_DAYS(date) 
    給出一個日期date,返回一個天數(從0年的天數)。 
    mysql> select TO_DAYS(950501); 
    -> 728779 
    mysql> select TO_DAYS('1997-10-07'); 
    -> 729669

    TO_DAYS()不打算用于使用格列高里歷(1582)出現前的值。

    FROM_DAYS(N) 
    給出一個天數N,返回一個DATE值。 
    mysql> select FROM_DAYS(729669); 
    -> '1997-10-07'

    TO_DAYS()不打算用于使用格列高里歷(1582)出現前的值。

    DATE_FORMAT(date,format) 
    根據format字符串格式化date值。下列修飾符可以被用在format字符串中: %M 月名字(January……December) 
    %W 星期名字(Sunday……Saturday) 
    %D 有英語前綴的月份的日期(1st, 2nd, 3rd, 等等。) 
    %Y 年, 數字, 4 位 
    %y 年, 數字, 2 位 
    %a 縮寫的星期名字(Sun……Sat) 
    %d 月份中的天數, 數字(00……31) 
    %e 月份中的天數, 數字(0……31) 
    %m 月, 數字(01……12) 
    %c 月, 數字(1……12) 
    %b 縮寫的月份名字(Jan……Dec) 
    %j 一年中的天數(001……366) 
    %H 小時(00……23) 
    %k 小時(0……23) 
    %h 小時(01……12) 
    %I 小時(01……12) 
    %l 小時(1……12) 
    %i 分鐘, 數字(00……59) 
    %r 時間,12 小時(hh:mm:ss [AP]M) 
    %T 時間,24 小時(hh:mm:ss) 
    %S 秒(00……59) 
    %s 秒(00……59) 
    %p AM或PM 
    %w 一個星期中的天數(0=Sunday ……6=Saturday ) 
    %U 星期(0……52), 這里星期天是星期的第一天 
    %u 星期(0……52), 這里星期一是星期的第一天 
    %% 一個文字“%”。

    所有的其他字符不做解釋被復制到結果中。

    mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y'); 
    -> 'Saturday October 1997' 
    mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s'); 
    -> '22:23:00' 
    mysql> select DATE_FORMAT('1997-10-04 22:23:00', 
    '%D %y %a %d %m %b %j'); 
    -> '4th 97 Sat 04 10 Oct 277' 
    mysql> select DATE_FORMAT('1997-10-04 22:23:00', 
    '%H %k %I %r %T %S %w'); 
    -> '22 22 10 10:23:00 PM 22:23:00 00 6' 
    MySQL3.23中,在格式修飾符字符前需要%。在MySQL更早的版本中,%是可選的。

    TIME_FORMAT(time,format) 
    這象上面的DATE_FORMAT()函數一樣使用,但是format字符串只能包含處理小時、分鐘和秒的那些格式修飾符。 
    其他修飾符產生一個NULL值或0。 
    CURDATE()

    CURRENT_DATE 
    以'YYYY-MM-DD'或YYYYMMDD格式返回今天日期值,取決于函數是在一個字符串還是數字上下文被使用。 
    mysql> select CURDATE(); 
    -> '1997-12-15' 
    mysql> select CURDATE() + 0; 
    -> 19971215

    CURTIME()

    CURRENT_TIME 
    以'HH:MM:SS'或HHMMSS格式返回當前時間值,取決于函數是在一個字符串還是在數字的上下文被使用。 
    mysql> select CURTIME(); 
    -> '23:50:26' 
    mysql> select CURTIME() + 0; 
    -> 235026

    NOW()

    SYSDATE()

    CURRENT_TIMESTAMP 
    以'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式返回當前的日期和時間,取決于函數是在一個字符串還是在數字的 
    上下文被使用。 
    mysql> select NOW(); 
    -> '1997-12-15 23:50:26' 
    mysql> select NOW() + 0; 
    -> 19971215235026

    UNIX_TIMESTAMP()

    UNIX_TIMESTAMP(date) 
    如果沒有參數調用,返回一個Unix時間戳記(從'1970-01-01 00:00:00'GMT開始的秒數)。如果UNIX_TIMESTAMP()用一 
    個date參數被調用,它返回從'1970-01-01 00:00:00' GMT開始的秒數值。date可以是一個DATE字符串、一個DATETIME 
    字符串、一個TIMESTAMP或以YYMMDD或YYYYMMDD格式的本地時間的一個數字。 
    mysql> select UNIX_TIMESTAMP(); 
    -> 882226357 
    mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00'); 
    -> 875996580

    當UNIX_TIMESTAMP被用于一個TIMESTAMP列,函數將直接接受值,沒有隱含的“string-to-unix-timestamp”變換。

    FROM_UNIXTIME(unix_timestamp) 
    以'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式返回unix_timestamp參數所表示的值,取決于函數是在一個字符串 
    還是或數字上下文中被使用。 
    mysql> select FROM_UNIXTIME(875996580); 
    -> '1997-10-04 22:23:00' 
    mysql> select FROM_UNIXTIME(875996580) + 0; 
    -> 19971004222300

    FROM_UNIXTIME(unix_timestamp,format) 
    返回表示 Unix 時間標記的一個字符串,根據format字符串格式化。format可以包含與DATE_FORMAT()函數列出的條 
    目同樣的修飾符。 
    mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(), 
    '%Y %D %M %h:%i:%s %x'); 
    -> '1997 23rd December 03:43:30 x'

    SEC_TO_TIME(seconds) 
    返回seconds參數,變換成小時、分鐘和秒,值以'HH:MM:SS'或HHMMSS格式化,取決于函數是在一個字符串還是在數字 
    上下文中被使用。 
    mysql> select SEC_TO_TIME(2378); 
    -> '00:39:38' 
    mysql> select SEC_TO_TIME(2378) + 0; 
    -> 3938

    TIME_TO_SEC(time) 
    返回time參數,轉換成秒。 
    mysql> select TIME_TO_SEC('22:23:00'); 
    -> 80580 
    mysql> select TIME_TO_SEC('00:39:38'); 
    -> 2378
    DATE_FORMAT(date,format) 
    根據format字符串格式化date值。下列修飾符可以被用在format字符串中: %M 月名字(January……December) 
    %W 星期名字(Sunday……Saturday) 
    %D 有英語前綴的月份的日期(1st, 2nd, 3rd, 等等。) 
    %Y 年, 數字, 4 位 
    %y 年, 數字, 2 位 
    %a 縮寫的星期名字(Sun……Sat) 
    %d 月份中的天數, 數字(00……31) 
    %e 月份中的天數, 數字(0……31) 
    %m 月, 數字(01……12) 
    %c 月, 數字(1……12) 
    %b 縮寫的月份名字(Jan……Dec) 
    %j 一年中的天數(001……366) 
    %H 小時(00……23) 
    %k 小時(0……23) 
    %h 小時(01……12) 
    %I 小時(01……12) 
    %l 小時(1……12) 
    %i 分鐘, 數字(00……59) 
    %r 時間,12 小時(hh:mm:ss [AP]M) 
    %T 時間,24 小時(hh:mm:ss) 
    %S 秒(00……59) 
    %s 秒(00……59) 
    %p AM或PM 
    %w 一個星期中的天數(0=Sunday ……6=Saturday ) 
    %U 星期(0……52), 這里星期天是星期的第一天 
    %u 星期(0……52), 這里星期一是星期的第一天 
    %% 一個文字“%”。 所有的其他字符不做解釋被復制到結果中。

    mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y'); 
    -> 'Saturday October 1997' 
    mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s'); 
    -> '22:23:00' 
    mysql> select DATE_FORMAT('1997-10-04 22:23:00', 
    '%D %y %a %d %m %b %j'); 
    -> '4th 97 Sat 04 10 Oct 277' 
    mysql> select DATE_FORMAT('1997-10-04 22:23:00', 
    '%H %k %I %r %T %S %w'); 
    -> '22 22 10 10:23:00 PM 22:23:00 00 6' 
    MySQL3.23中,在格式修飾符字符前需要%。在MySQL更早的版本中,%是可選的。

    TIME_FORMAT(time,format) 
    這象上面的DATE_FORMAT()函數一樣使用,但是format字符串只能包含處理小時、分鐘和秒的那些格式修飾符。

    其他修飾符產生一個NULL值或0。 
    CURDATE()

    CURRENT_DATE 
    以'YYYY-MM-DD'或YYYYMMDD格式返回今天日期值,取決于函數是在一個字符串還是數字上下文被使用。 
    mysql> select CURDATE(); 
    -> '1997-12-15' 
    mysql> select CURDATE() + 0; 
    -> 19971215

    CURTIME()

    CURRENT_TIME 
    以'HH:MM:SS'或HHMMSS格式返回當前時間值,取決于函數是在一個字符串還是在數字的上下文被使用。 
    mysql> select CURTIME(); 
    -> '23:50:26' 
    mysql> select CURTIME() + 0; 
    -> 235026

    NOW()

    SYSDATE()

    CURRENT_TIMESTAMP 
    以'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式返回當前的日期和時間,取決于函數是在一個字符串還是在數字的 
    上下文被使用。 
    mysql> select NOW(); 
    -> '1997-12-15 23:50:26' 
    mysql> select NOW() + 0; 
    -> 19971215235026

    UNIX_TIMESTAMP()

    UNIX_TIMESTAMP(date) 
    如果沒有參數調用,返回一個Unix時間戳記(從'1970-01-01 00:00:00'GMT開始的秒數)。如果UNIX_TIMESTAMP()用一個date參數被調用,它返回從'1970-01-01 00:00:00' GMT開始的秒數值。date可以是一個DATE字符串、一個DATETIME字符串、一個TIMESTAMP或以YYMMDD或YYYYMMDD格式的 本地時間的一個數字。 
    mysql> select UNIX_TIMESTAMP(); 
    -> 882226357 
    mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00'); 
    -> 875996580

    當UNIX_TIMESTAMP被用于一個TIMESTAMP列,函數將直接接受值,沒有隱含的“string-to-unix-timestamp”變換 www.knowsky.com

    FROM_UNIXTIME(unix_timestamp) 
    以'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式返回unix_timestamp參數所表示的值,取決于函數是在一個字符串還是或數字上下文中被使用。 
    mysql> select FROM_UNIXTIME(875996580); 
    -> '1997-10-04 22:23:00' 
    mysql> select FROM_UNIXTIME(875996580) + 0; 
    -> 19971004222300

    FROM_UNIXTIME(unix_timestamp,format) 
    返回表示 Unix 時間標記的一個字符串,根據format字符串格式化。format可以包含與DATE_FORMAT()函數列出的條目同樣的修飾符。 
    mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(), 
    '%Y %D %M %h:%i:%s %x'); 
    -> '1997 23rd December 03:43:30 x'

    SEC_TO_TIME(seconds) 
    返回seconds參數,變換成小時、分鐘和秒,值以'HH:MM:SS'或HHMMSS格式化,取決于函數是在一個字符串還是在數字上下文中被使用。 
    mysql> select SEC_TO_TIME(2378); 
    -> '00:39:38' 
    mysql> select SEC_TO_TIME(2378) + 0; 
    -> 3938

    TIME_TO_SEC(time) 
    返回time參數,轉換成秒。 
    mysql> select TIME_TO_SEC('22:23:00'); 
    -> 80580 
    mysql> select TIME_TO_SEC('00:39:38'); 
    -> 2378

    posted @ 2012-03-07 16:31 段旭 閱讀(261) | 評論 (0)編輯 收藏

    構建jQuery對象

    (function( window, undefined ) {

       

        var jQuery = (function() {

           // 構建jQuery對象

           var jQuery = function( selector, context ) {

               return new jQuery.fn.init( selector, context, rootjQuery );

           }

       

           // jQuery對象原型

           jQuery.fn = jQuery.prototype = {

               constructor: jQuery,

               init: function( selector, context, rootjQuery ) {

                  // selector有以下7種分支情況:

                  // DOM元素

                  // body(優化)

                  // 字符串:HTML標簽、HTML字符串、#id、選擇器表達式

                  // 函數(作為ready回調函數)

                  // 最后返回偽數組

               }

           };

       

           // Give the init function the jQuery prototype for later instantiation

           jQuery.fn.init.prototype = jQuery.fn;

       

           // 合并內容到第一個參數中,后續大部分功能都通過該函數擴展

           // 通過jQuery.fn.extend擴展的函數,大部分都會調用通過jQuery.extend擴展的同名函數

           jQuery.extend = jQuery.fn.extend = function() {};

          

           // jQuery上擴展靜態方法

           jQuery.extend({

               // ready bindReady

               // isPlainObject isEmptyObject

               // parseJSON parseXML

               // globalEval

               // each makeArray inArray merge grep map

               // proxy

               // access

               // uaMatch

               // sub

               // browser

           });

     

            // 到這里,jQuery對象構造完成,后邊的代碼都是對jQueryjQuery對象的擴展

           return jQuery;

       

        })();

       

        window.jQuery = window.$ = jQuery;

    })(window);

    posted @ 2012-02-22 13:10 段旭 閱讀(773) | 評論 (0)編輯 收藏

    常用正則式

    常用的數字正則(嚴格匹配)
    正則 含義
    ^[1-9]\d*$ 匹配正整數
    ^-[1-9]\d*$ 匹配負整數
    ^-?[1-9]\d*$ 匹配整數
    ^[1-9]\d*|0$ 匹配非負整數(正整數 + 0)
    ^-[1-9]\d*|0$ 匹配非正整數(負整數 + 0)
    ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 匹配正浮點數
    ^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 匹配負浮點數
    ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$ 匹配浮點數
    ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ 匹配非負浮點數(正浮點數 + 0)
    ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$ 匹配非正浮點數(負浮點數 + 0)

    常用字符串正則
    正則 含義 補充
    ^[A-Za-z]+$ 匹配由26個英文字母組成的字符串 或 /^[a-z]+$/i
    ^[A-Z]+$ 匹配由26個英文字母的大寫組成的字符串
    ^[a-z]+$ 匹配由26個英文字母的小寫組成的字符串
    ^[A-Za-z0-9]+$ 匹配由數字和26個英文字母組成的字符串 注意\w包含下劃線_
    ^\w+$ 匹配由數字、26個英文字母或者下劃線組成的字符串

    匹配中文字符
    普遍使用的正則是[\u4e00-\u9fa5],但這個范圍并不完整。例如:
    /[\u4e00-\u9fa5]/.test( '?' ) // 測試部首?,返回false
    根據Unicode 5.0版編碼,要準確的判斷一個中文字符要包括:
    范圍 含義 范圍 含義
    2E80-2EFF CJK 部首補充 2F00-2FDF 康熙字典部首
    3000-303F CJK 符號和標點 31C0-31EF CJK 筆畫
    3200-32FF 封閉式 CJK 文字和月份 3300-33FF CJK 兼容
    3400-4DBF CJK 統一表意符號擴展 A 4DC0-4DFF 易經六十四卦符號
    4E00-9FBF CJK 統一表意符號 F900-FAFF CJK 兼容象形文字
    FE30-FE4F CJK 兼容形式 FF00-FFEF 全角ASCII、全角標點
    因此,正確的匹配中文字符正則表達式為:
    var rcjk = /[\u2E80-\u2EFF\u2F00-\u2FDF\u3000-\u303F\u31C0-\u31EF\u3200-\u32FF\u3300-\u33FF\u3400-\u4DBF\u4DC0-\u4DFF\u4E00-\u9FBF\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFFEF]+/g;
    如果不希望匹配標點、符號,在正則中去掉對應的范圍即可:
    3000-303F CJK 符號和標點 FF00-FFEF 全角ASCII、全角標點

    匹配雙字節字符(包括漢字在內)
    [^\x00-\xff],可以用來計算字符串的長度(一個雙字節字符長度計2,ASCII字符計1),代碼示例如下:
    console.info( "abc".replace( /[^\x00-\xff]/g,"aa" ).length ) // 3
    console.info( "漢字".replace( /[^\x00-\xff]/g,"aa" ).length ) // 4
    console.info( "abc漢字".replace( /[^\x00-\xff]/g,"aa").length ) // 7

    posted @ 2012-02-22 10:57 段旭 閱讀(269) | 評論 (0)編輯 收藏

    JQuery總體架構

    (function( window, undefined ) {
    // 構造jQuery對象
    var jQuery = function( selector, context ) {
    return new jQuery.fn.init( selector, context, rootjQuery );
    }
    // 工具函數 Utilities
    // 異步隊列 Deferred
    // 瀏覽器測試 Support
    // 數據緩存 Data
    // 隊列 queue
    // 屬性操作 Attribute
    // 事件處理 Event
    // 選擇器 Sizzle
    // DOM遍歷
    // DOM操作
    // CSS操作
    // 異步請求 Ajax
    // 動畫 FX
    // 坐標和大小
    window.jQuery = window.$ = jQuery;
    })(window);
    從上邊的注釋看,jQuery的源碼結構相當清晰、條理,不像代碼那般晦澀和讓人糾結。

    posted @ 2012-02-22 10:43 段旭 閱讀(228) | 評論 (0)編輯 收藏

    自調用匿名函數 self-invoking anonymous function

    (function( window, undefined ) {

        // jquery code

    })(window);

    1.這是一個自調用匿名函數。什么東東呢?在第一個括號內,創建一個匿名函數;第二個括號,立即執行

    2.為什么要創建這樣一個“自調用匿名函數”呢?

    通過定義一個匿名函數,創建了一個“私有”的命名空間,該命名空間的變量和方法,不會破壞全局的命名空間。這點非常有用也是一個JS框架必須支持的功能,jQuery被應用在成千上萬的JavaScript程序中,必須確保jQuery創建的變量不能和導入他的程序所使用的變量發生沖突。

    3.匿名函數從語法上叫函數直接量,JavaScript語法需要包圍匿名函數的括號,事實上自調用匿名函數有兩種寫法(注意標紅了的右括號):

    (function() {

        console.info( this );

        console.info( arguments );

     }( window ) 
    );

    (function() {

        console.info( this );

        console.info( arguments );

     }
    )( window );

    4.為什么要傳入window呢?

    通過傳入window變量,使得window由全局變量變為局部變量,當在jQuery代碼塊中訪問window時,不需要將作用域鏈回退到頂層作用域,這樣可以更快的訪問window;這還不是關鍵所在,更重要的是,將window作為參數傳入,可以在壓縮代碼時進行優化,看看jquery-1.6.1.min.js:

     

    (function(a,b){})(window); // window 被優化為 a   

    5.為什么要在在參數列表中增加undefined呢?

    在 自調用匿名函數 的作用域內,確保undefined是真的未定義。因為undefined能夠被重寫,賦予新的值。

      undefined = "now it's defined";

      alert( undefined );

    瀏覽器測試結果:

    瀏覽器

    測試結果

     結論

    ie

        now it's defined    

      可以改變

    firefox

    undefined

      不能改變

    chrome

    now it's defined

      可以改變

    opera

    now it's defined

      可以改變


     6. 注意到源碼最后的分號了嗎?

    分號是可選的,但省略分號并不是一個好的編程習慣;為了更好的兼容性和健壯性,請在每行代碼后加上分號并養成習慣。

     

     

    posted @ 2012-02-22 10:41 段旭 閱讀(1142) | 評論 (0)編輯 收藏

    jquery設置元素的readonly和disabled

    Jquery的api中提供了對元素應用disabled和readonly屬性的方法,在這里記錄下。如下:
     1.readonly
        $('input').attr("readonly","readonly")//將input元素設置為readonly
        $('input').removeAttr("readonly");//去除input元素的readonly屬性
      
        if($('input').attr("readonly")==true)//判斷input元素是否已經設置了readonly屬性

     

        對于為元素設置readonly屬性和取消readonly屬性的方法還有如下兩種:
        $('input').attr("readonly",true)//將input元素設置為readonly
        $('input').attr("readonly",false)//去除input元素的readonly屬性

     

        $('input').attr("readonly","readonly")//將input元素設置為readonly
        $('input').attr("readonly","")//去除input元素的readonly屬性
     2.disabled
     

        $('input').attr("disabled","disabled")//將input元素設置為disabled
        $('input').removeAttr("disabled");//去除input元素的disabled屬性
      
        if($('input').attr("disabled")==true)//判斷input元素是否已經設置了disabled屬性

      

      對于為元素設置disabled屬性和取消disabled屬性的方法還有如下兩種:
        $('input').attr("disabled",true)//將input元素設置為disabled
        $('input').attr("disabled",false)//去除input元素的disabled屬性

     

        $('input').attr("disabled","disabled")//將input元素設置為disabled
        $('input').attr("disabled","")//去除input元素的disabled屬性

    posted @ 2012-02-21 15:29 段旭 閱讀(258) | 評論 (0)編輯 收藏

    網友整理三亞防宰攻略手冊

      針對微博熱議的“三亞旅游被宰”經歷,新浪旅游根據網友留言及評論整理了一份三亞拒絕挨宰攻略。

      跟團游

      團隊旅行中,最大塊的挨宰費主要是購物店、燒香;小的費用主要是看人妖、潛水、互動節目??傊詈竽愕幕ㄤN很可能超出團費。

      有些人在當地報名參加“一日游”等,常見的被宰方式是從這家旅行社被“賣”到另一家旅行社,可能還要忍受非常惡劣的服務態度。

      防宰攻略:

      1.選擇正規、規模大的旅行社。

      2.在簽訂合同的時候,細節一定要問清楚,有些東西需要額外注明在合同中,以確保自身的利益能夠得到保障。

      3.在切身利益受到侵害的時候,立刻撥打相關投訴電話,必要時報警。

      自助游

      【吃海鮮】

      要么缺斤短兩,要么就是被天價的海鮮所“打敗”,少則幾百,多則幾千,普通游客難以承受。

      防宰攻略:

      1.如果有導游、出租車司機、摩托車夫、三輪車夫向你極力推薦某某海鮮店,要多留個心眼,或許到了那里你就身不由己了……不要聽信路邊發廣告、發名片的游說。

      2.吃海鮮可以考慮海鮮市場。可以買海鮮直接加工,成本相對低廉,方便且便宜。

      3.遠離黑心海鮮店。

      黑心海鮮店一般分布在高端酒店旁或者離市區較遠的地方,騙人的方法有的極其夸張。

      A.當你指向一個東西、問價格的時候,小二順勢拿出就在你眼前拍死,你還沒回過神這個東西已經需要你來買單了!

      B.你問價格的時候,老板熱情地告訴你不貴啦才4元每斤啦,但等你結賬的時候可能是40元每斤或者400元每斤。

      C.嚴重缺斤短兩。

      【買水果】

      在三亞買美味的熱帶水果,也要格外注意。

      1.自帶小秤。

      缺斤短兩是小商販們最慣用的伎倆,而我們也應該同樣細心一些,稱一稱所購買的物品到底多重(先談價錢再亮秤)。

      2.去正規的水果市場,店鋪多,市場管理相對完善。

      3.如果當地有熟人,可以讓他帶你去買。

      【景點游玩】

      1.網上提前訂門票。一般網絡訂票能更優惠,建議提前購票。

      2.不必每個景點都去,去一些重點和有代表性的景點便可。

      3.充分利用公交車、旅游專線巴士、機場巴士等公共資源。

      4.包車線路一定要自己設計,否則容易被宰。

      5.慎買珍珠、水晶等。

      6.三輪車和兩輪摩的,建議不要乘坐,危險并且很容易被“宰”。

      7.住小酒店,建議不要讓服務員幫你叫車,說不定會叫來跟他們有利益鏈條的相關車輛。

      8.無招勝有招。在亞龍灣、海棠灣的酒店盡情享受陽光,盡量避免外出。

    posted @ 2012-01-30 17:12 段旭 閱讀(223) | 評論 (0)編輯 收藏

    [IBM]構建輕量級 Batch 框架處理 DB2 Content Manager 8.3 大量數據導入

    【來源】http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0908luyx/

    本文介紹了如何使用多線程來構建輕量級 Batch 框架,將大量的數據遷移到 IBM DB2 Content Manager 8.3 中。通過本文的學習,讀者可以了解如何通過使用多線程調用 IBM DB2 Content Manager API 構建的框架來啟動,暫停,恢復,停止,放緩等操作。

    在用 API 導入大量數據的過程中,如果沒有框架很難有效的對整個過程控制,僅僅通過日志來分析解決問題總是很浪費時間,并且效率不太理想。

    本文的內容放在了如何使用多線程和配置文件來構建 Batch 框架來處理大數量導入的問題。

    隨著 IBM DB2 Content Manager(簡稱 IBM CM)產品的不斷成熟,越來越多的內容管理系統需要遷移到 IBM CM 中來,這些需要遷移的數據通常首先把結構化的內容導到文本文件中,與之相對應的圖像和 pdf 文件通常放在對應的文件夾中,圖像和 pdf 對應的文件夾路徑也通常存放在文本文件中,然后遷移程序遍歷文本文件,把對應的 Item 遷移到 IBM CM 中。這些需要遷移的數據通常都有幾百 G,如何有效的控制遷移過程是一個很大的挑戰,因此我們必須構建一個輕量級的 batch 處理框架來控制整個數據的遷移周期,記錄處理過程中的錯誤,保證數據的一致性。

    同時,在用 API 導入數據的過程中,被導入數據總是千邊萬化,無效的映射導入數據和 DB2 Content Manager 的項,導致工作變得復雜,同時使的設計和代碼冗余,并且使重用,維護和擴展履步為艱難。

    為了克服所提到的挑戰,這個 batch 框架必須要有以下功能:

    • 用戶出于不影響生產環境性能的考慮,可以暫時停止數據的遷移,或者減緩遷移處理的頻率,即框架必須具有 suspend 和 slowdown 功能。
    • 用戶可以讓暫停處理的系統繼續處理,即框架必須具有 resume 功能。
    • 用戶可以讓系統停止處理,修改某些配置,然后繼續處理,即框架必須有 re-start 功能。
    • 處理過程中發生的錯誤,警告系統必須記錄下來,用戶可以根據這些記錄來修正數據。
    • 通過配置文件建立規則來解決數據千邊萬化的問題。

    構建框架

    構建交互性

    要使框架有交互性,我們必須有三個個線程:客戶端線程,服務端線程,工作線程??蛻舳司€程負責發出工作指令,服務端線程接受這些指令并調用工作線程來做實際的工作。對于客戶端和服務器交互,在沒有 web 服務器支持的情況下,我們可以采用一種古老但是很有效的做法:socket 編程。 Java socket 對象的 accept 方法會一直阻塞直到客戶端有程序輸入,當客戶端有新的命令輸入的時候,服務器端從 socket 中讀出命令,然后執行命令。下面是示例程序,Client.java 代表客戶端程序,Server.java 代表服務器端程序,Worker.java 代表工作程序 ,Config.java 代表系統中一些參數配置。


    清單 1. 客戶端程序
    package com.ibm.batch.sample;
    
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.net.Socket;
    import org.apache.log4j.Logger;
    
    public class Client {
    	private Config config = null;
    	public void setConfig(Config config) {
    		this.config = config;
    	}
    	private Logger logger = Logger.getLogger(Client.class);
    	public void sendCommand(String command) {
    		Socket socket = null;
    		OutputStream out = null;
    		BufferedWriter writer = null;
    		try {
    			// establish the connection with server.
    			socket = new Socket(config.getHost(), config.getSocketPort());
    			out = socket.getOutputStream();
    			writer = new BufferedWriter(new OutputStreamWriter(out));
    			// send the command to server
    			writer.write(command);
    			writer.flush();
    		} catch (IOException e) {
    			logger.error(e.getMessage(), e);
    			throw new RuntimeException(e);
    		}
    	}
    }
    


    清單 2. 服務器端程序
    package com.ibm.batch.sample;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.ServerSocket;
    import java.net.Socket;
    import com.ibm.batch.sample.util.ResourceUtils;
    
    public class Server {
    	private Config config = null;
    	private boolean processing = true;	
    	private Worker worker = null;
    	public void setConfig(Config config) {
    		this.config = config;
    	}
    	public static void main(String[] args) {
    		Server server = new Server();
    		// create the work thread
    		Worker worker = server.createWorker(args);
    		worker.start();		
    		server.receiveAndExecuteCommand();
    	}
    	private Worker createWorker(String[] args) {
    		Worker worker = new Worker();
    		this.worker = worker;
    		return worker;
    	}
    	/**
    	 * receive the command from client and execute the command. the method is
    	 * keeping running until client send the 'stop' command.
    	 * 
    	 * @throws Exception
    	 */
    	public void receiveAndExecuteCommand() {
    		ServerSocket serverSocket = buildSocketConnection();
    		// loop until client send 'stop' command
    		while (processing) {
    			Socket socket = null;
    			try {
    			socket = serverSocket.accept();
    			String commandLine = readCommandFromSocket(socket);
                    executeCommand(commandLine);
    			} catch (Exception e) {
    				throw new RuntimeException(e);
    			} finally {
    				ResourceUtils.closeSocket(socket);
    			}
    		}
    	}
    	private void executeCommand(String commandLine) {
    		// TODO Auto-generated method stub
    	}
    
    	/**
    	 * read the command from the socket
    	 * 
    	 * @param socket
    	 * @return
    	 */
    	private String readCommandFromSocket(Socket socket) {
    		InputStream in = null;
    		BufferedReader bufferedReader = null;
    		String commandLine = null;
    		try {
    			in = socket.getInputStream();
    			bufferedReader = new BufferedReader(new InputStreamReader(in));
    			commandLine = bufferedReader.readLine();
    		} catch (IOException e) {
    			throw new RuntimeException(e);
    		} finally {
    			ResourceUtils.closeInputStream(in);
    			ResourceUtils.closeReader(bufferedReader);
    		}
    		return commandLine;
    	}
    	/**
    	 * build the socket.
    	 * 
    	 * @return
    	 */
    	private ServerSocket buildSocketConnection() {
    		// prepare the socket for client to connect.
    		ServerSocket serverSocket;
    		try {
    			serverSocket = new ServerSocket(config.getSocketPort());
    		} catch (java.net.BindException e1) {
    			throw new RuntimeException("Socket port already in use.", e1);
    		} catch (IOException ioe) {
    			throw new RuntimeException(ioe);
    		}
    		return serverSocket;
    	}
    }
    


    清單 3. 工作程序
    package com.ibm.batch.sample;
    
    import org.apache.log4j.Logger;
    
    public class Worker extends Thread {
    	Logger logger = Logger.getLogger(Worker.class);
    	/**
    	 * the main method for create item function.
    	 */
    	public void run() {
    		createItem();
    	}
    	/**
    	 * do the real job
    	 */
    	private void createItem() {	 		
    	}
    }
    

    添加 suspend 和 slowdown 處理命令

    大數量的數據遷移一般是在周末或者晚上進行,但是如果客戶的歷史數據太大,在周末或者晚上數據可能處理不完,為了不影響生產環境的性能,我們必須能夠在客戶的工作時間暫緩處理或者降低處理的頻率,把 cpu 等資源讓給客戶程序,也就是說處理線程 worker 的工作可以 suspend 或者 slowdow 。為了讓 worker 線程知道需要 suspend 當前處理,我們可以在 worker 內部設置一個布爾變量 isSuspend,當程序在循環創建 CM item 的時候,我們每次都判斷一下這個布爾變量 isSuspend,當其為 ture 的時候,程序就調用線程的 wait 方法中斷當前線程的處理,wait 方法還可以接受一個以微秒為單位的時間參數,當時間到達 wait 指定的時間的時候,程序繼續創建 CM Item 。為了多線程之間的變量可見性,我們必須把 worker 的 isSuspend 變量和 suspendTime 設置為 volatile 。同理我們設置一個布爾變量 isSlowdown 以及 slowdowTime 。示例程序如下:


    清單 4. 工作程序
    package com.ibm.batch.sample;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import org.apache.log4j.Logger;
    import com.ibm.batch.sample.util.ResourceUtils;
    
    public class Worker extends Thread {
    	Logger logger = Logger.getLogger(Worker.class);	
    	private volatile boolean isSlowdown = false;
    	private volatile Double slowdownTime;
    	private volatile boolean isSuspend;
    	private volatile Double suspendTime;
    	public void setSlowdown(boolean isSlowdown) {
    		this.isSlowdown = isSlowdown;
    	}
    	public void setSlowdownTime(Double slowdownTime) {
    		this.slowdownTime = slowdownTime;
    	}
    	public void setSuspend(boolean isSuspend) {
    		this.isSuspend = isSuspend;
    	}
    	public void setSuspendTime(Double suspendTime) {
    		this.suspendTime = suspendTime;
    	}
    	public boolean isSlowdown() {
    		return isSlowdown;
    	}
    	public Double getSlowdownTime() {
    		return slowdownTime;
    	}
    	public boolean isSuspend() {
    		return isSuspend;
    	}
    	public Double getSuspendTime() {
    		return suspendTime;
    	}
    	protected Object semaphore = new Object();
    	private Config config;
    	public void setConfig(Config config) {
    		this.config = config;
    	}
    


    清單 5. 主方法
    /**
    	 * the main method for create item function.
    	 */
    	public void run() {
    		BufferedReader reader = null;
    		try {
    			reader = getFileReader();
    			String oneLine = null;
    			while ((oneLine = reader.readLine()) != null) {
    				if (isSlowdown()) {
    					sleep4GivenTime();
    				}
    				if (isSuspend()) {
    					suspend4SomeTime();
    				}
    				createItem(oneLine);
    			}
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		} finally {
    			ResourceUtils.closeReader(reader);
    		}
    	}
    
    	/**
    	 * current thread sleep for some time,the unit is minute.
    	 */
    	protected void sleep4GivenTime() {
    		try {
    			Thread.sleep((long) (slowdownTime.doubleValue() * 1000));
    		} catch (InterruptedException e) {
    			// do nothing
    		}
    	}
    


    清單 6.Suspend 方法
    			
    /**
     * suspend working for given time.
     */
    protected void suspend4SomeTime() {
    	synchronized (semaphore) {
    	try {
    	Double suspendTime = getSuspendTime();
    	if (suspendTime != null) {
    		double suspendTimeDouble = suspendTime.doubleValue() * 60 * 1000;
    		semaphore.wait((long) suspendTimeDouble);
    	} else {
    	                     semaphore.wait();
    	}
    	} catch (InterruptedException e) {
    	// tell user that the processing started
    	logger.info("suspend is over,system is continue processing .");
    	}
    	}
    	}
    	/**
    	 * do the real job
    	 * 
    	 * @throws Exception
    	 */
    	private void createItem(String oneLine) throws Exception {
    	}
    	private BufferedReader getFileReader() throws FileNotFoundException {
    		String fileName = config.getFileName();
    		File processingFile = new File(fileName);
    		BufferedReader reader = new BufferedReader(new FileReader(
    				processingFile));
    		return reader;
    	}
    }
    

    添加 resume 功能

    在程序暫停處理以后,我們可以提前終止 suspend,讓框架繼續處理,也就是框架必須有 resume 功能。我們調用 Worker.java 對象上的 notify 方法來實現這個功能,示例如下:


    清單 7.Resume
    public class Worker extends Thread {
    	/**
    	 * resume the working.
    	 */
    	public void continueWorking() {
    		cleanSuspend();
    		synchronized (semaphore) {
    			semaphore.notify();
    		}
    	}
    }
    
     

    添加 stop 和 re-start 功能

    有時候用戶因為一些原因(例如修改配置文件)想停止程序的執行,所以框架必須有 stop 的功能,但是 stop 的時候我們必須注意記錄程序處理到的行數,這樣客戶再開始執行的時候能夠從上次執行的斷點繼續執行,也就是框架具備了 re-start 功能,這是 batch 程序必須具備的一種很重要的功能,re-start 功能有多種實現方法,我們這里采取一種簡單的方法,在 stop 的時候,把當前處理的記錄到一個文本文件中去,下次啟動的時候從上次最后處理的對象開始進行處理。所以我們在 Worker.java 中增加一個 keepProcessing 布爾變量,在循環創建 CM Item 的時候 , 我們每次都判斷一下這個值是否為 true,如果為 false 的話,我們就停止循環處理,在 Worker.java 中還要增加一個 moveReaderToLastProcess 方法,把 reader 重新定向到上次處理點。


    清單 8. 停止和重啟
    public class Worker extends Thread {
    	private volatile boolean keepProcessing;
    	public boolean isKeepProcessing() {
    		return keepProcessing;
    	}
    	public void setKeepProcessing(boolean keepProcessing) {
    		this.keepProcessing = keepProcessing;
    	}
    	/**
    	 * the main method for create item function.
    	 */
    	public void run() {
    		BufferedReader reader = null;
    		try {
    			long lastProcessedRow = config.getLastProcessedRow();	
    			reader = moveReaderToLastProcess(lastProcessedRow);
    			String oneLine = null;
    			connectToCM();
    			while (((oneLine = reader.readLine()) != null)
    					&& isKeepProcessing()) {
    				if (isSlowdown()) {
    					sleep4GivenTime();
    				}
    				if (isSuspend()) {
    					suspend4SomeTime();
    				}
    				createItem(oneLine);
    				lastProcessedRow++;
    			}
    			logCurrentProcessingLine(lastProcessedRow);
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		} finally {
    			ResourceUtils.closeReader(reader);
    		}
    	}	
    	private void logCurrentProcessingLine(long lastProcessedRow) {
    		config.setLastProcessedRow(lastProcessedRow);
    	}	
    	/**
    	 * move current reader position to last process postion
    	 * @return
    	 * @throws IOException
    	 */
    private BufferedReader moveReaderToLastProcess(long lastProcessedRow) 
             throws IOException {
    		// get the file reader
    		BufferedReader reader = getFileReader();	
    			
    		// move the reader to the start row -1.
    		int count = 0;
    		while (count < lastProcessedRow-1) {
    			reader.readLine();			
    			count++;
    		}
    		return reader;
    	}
    }
    

    添加錯誤處理功能

    剛才我們調用的 createItem 方法是直接拋出異常的,但是這樣的處理實際上是錯誤的,因為在 batch 處理過程中,我們不希望在處理某一個 item 出錯導致剩余的 item 不再處理,所以我們在 catch 里面對異常進行分類處理,我們 catch 住非檢查異常(runtime exception),通常非檢查異常是不可以恢復的,所以我們直接拋出,讓程序結束處理。對于其余的異常,我們只是在日志中記錄下來,并不拋出。在全部處理結束以后,用戶可以檢查日志來進行相應的處理。示例代碼如下:


    清單 9. 錯誤處理
    public class Worker extends Thread {
    	/**
    	 * do the real job
    	 * 
    	 * @throws Exception
    	 */
    	private void createItem(String oneLine) throws Exception {
    		try {
    			//create the item from one line
    		}catch (RuntimeException e) {
    			throw e;
    		}catch (Exception e) {
    			logger.error(e.getMessage(),e);
    		}
    	}
    }
    

    添加創建 CM item 功能

    下面的內容放在了如何使用配置文件來處理導入的問題。

    通過調用和運行 API 來處理數據的導入,我們首先定義一個基本信息的配置文件,用來制定連接的信息,其他配置文件的目錄,工作的目錄等有關導入需要的參數。然后定義導入數據和 DB2 Content Manager 的項的映射配置文件。配置文件定義結束后,我們就可以調用API來啟動相應的導入流程,在程序運行過程中,可以動態的更改配置,從而有效的處理導入的任務。

    在開發過程中,您可以靈活地定義各種配置文件以便實現多種導入規則,同時在程序運行中進行數據校驗,以防止冗余和非法數據被錯誤導入。

    下面的一些配置和代碼示例,以此介紹了如何定義配置文件,然后管理 API 來完成導入的任務。

    定義基本信息配置文件:在該文件中,須先設定 IBM DB2 Content Manager 的一些連接參數, 如:

    contentManagerDatabase=iCMnlsdb // 定義調用的數據庫名字
     contentManagerUsername=iCMadmin // 定義用戶名
     contentManagerPassword= password // 定義連接密碼
     contentManagerSchema=ICMADMIN // 定義具體的 schema

    您可以在代碼中用以上參數來實現對 IBM DB2 Content Manager 的連接,代碼示例:

    DKDatastoreICM dsICM = new DKDatastoreICM(); 
    // 創建連接 dsICM.connect("iCMnlsdb", "iCMadmin", "password", "SCHEMA=ICMADMIN");

    還需指定哪個文件夾存放映射文件,以及需導入的數據文件,如:

    mappingFilePath=config/rapid/mapping // 映射文件路徑
     dataFileFolder=config/rapid/data // 數據文件路徑

    也可定義一些參數來增強該導入的流程控制,如:

    runPhase=2 
    // 指定是第二階段導入,在導入時需更新已有的數據

    定義映射文件:該配置文件主要用于將用戶想要導入的數據映射到 IBM DB2 Content Manager 的 Item Type 中,您可自由定制該文件,使用戶遵循您定義的規范順利完成數據遷移。如:

    C001.del=c01 
     C002.del=c01

    該定義中 C001.del 和 C002.del 是需要導入的數據文件,c01 是對應的 Item Type 名字。這種定義方法可實現將多個數據文件導入同一個 Item Type 中。

    具體的對應關系如下:

    position=1|name=COMPANYNAME 
     position=2|name=COMPANYID 
     position=3|name=INPUTVALUE 
     position=-1|name=SPECIALVALUE|value=C1

    這個映射關系反映了數據文件中列數和 Item Type 中 attribute 的關系,如第一列在 Item Type 中代表了名字為 COMPANYNAME 的 attribute 。您也可定義一些特殊規則,如將 position 設為負數,以便反映該列是一個特殊的 attribute, 它的值是固定的。 比如將 position 設為 -1 時,名為 SPECIALVALUE 的 attribute 的值總是為 C1 。

    若您想實現將一個數據文件導入多個 Item Type 中,可在數據文件中加入一個特殊列,在映射文件中指定該列的列數,以及當該列的值和多種 Item Type 的映射關系。如:

    C003.del(position:3)

    這樣,C003.del 就不是單一的對應一個 Item Type,而是先去取第三列 INPUTVALUE 的值,再去對應表中查找到關聯的 Item Type 。該對應表可設成:

    Value1=c01 
     Value2=c02

    若第三列 INPUTDOCID 的值為 Value1 時,其對應的 Item Type 為 c01,同樣的當值為 Value2 時,會將該行數據導入到 c02 的 Item Type 中。

    調用 API 完成操作的代碼示例:在編寫代碼過程中,需要調用 DB2 Content Manager 的 API 來完成 Item Type 以及它包含的 attribute 的創建。上文已給出了通過參數來連接 Content Manager 的方法,下面的示例代碼用得到的 DKDatastoreICM 來實現具體的操作:


    清單 10. API 調用
    // Create an item / DDO / Root Component
    DKDDO ddo = dsICM.createDDO("S_withChild", itemPropertyOrSemanticType); 
    //createDDO(<Overall Item Type>, <Item Property / Semantic Type>);
    
    // Adding Multivalue Attributes to DDOs, multiple type can be used, 
    //here just give some example
     ddo.setData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,"S_varchar"), 
    "this is a string value");  
      //string
    
    ddo.setData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,"S_date"), 
    java.sql.Date.valueOf("2001-08-12"));
     //date
    
    ddo.setData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,"S_double"), 
    new Double("123")); 
    //double
    

    結束語

    通過本文的介紹,相信您對多線程構建的 Batch 框架實現大量數據遷移的過程,和通過配置文件的管理的 API 實現數據導入的過程也有了一定的了解和學習。您可靈活地實現一對一,一對多,多對多等各種映射關系,您也可以利用多線程來實現其他的功能的開發,編寫出更加富有創造性的軟件。


    參考資料

    學習

    獲得產品和技術

    • 使用可直接從 developerWorks 下載的 IBM 試用軟件 構建您的下一個 Linux 開發項目。

    posted @ 2011-12-28 17:16 段旭 閱讀(444) | 評論 (0)編輯 收藏

    主站蜘蛛池模板: 日韩精品亚洲aⅴ在线影院| 女人体1963午夜免费视频| 久久久久久99av无码免费网站| 久久精品亚洲中文字幕无码麻豆| 免费人成在线观看网站| 亚洲自偷精品视频自拍| 在线A级毛片无码免费真人| 亚洲色图激情文学| 啦啦啦高清视频在线观看免费 | 国产免费久久久久久无码| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 亚洲成aⅴ人片久青草影院按摩| 四虎影视免费永久在线观看| 黄床大片免费30分钟国产精品 | 岛国大片免费在线观看| 在线日本高清免费不卡| 亚洲经典千人经典日产| 亚洲人成高清在线播放| 操美女视频免费网站| 一级特黄特色的免费大片视频 | 国产一级片免费看| 久久国产精品免费一区| 一级免费黄色毛片| 美女被艹免费视频| 亚洲色图在线播放| 热99re久久免费视精品频软件| ssswww日本免费网站片| 在线精品亚洲一区二区| 亚洲va无码va在线va天堂| 成人激情免费视频| 成人啪精品视频免费网站| 免费中文熟妇在线影片| www.999精品视频观看免费| 一本到卡二卡三卡免费高| 日本高清不卡中文字幕免费| 亚洲精品在线免费观看视频| 中文字幕亚洲乱码熟女一区二区 | 亚洲色少妇熟女11p| 亚洲av无码专区在线观看下载 | 最近免费中文字幕大全免费版视频| 日本一道本不卡免费|