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

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

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

    本人用過,感覺不錯,向各位推薦一下,核心功能包括如下:

    1,通用的組織機構管理和權限控制;

    組織機構支持歷史組織變更記錄,滿足各類組織要求;
    權限控制采用國際通用的RBAC標準開發實現,支持權限報表;

    2,動態菜單;

    動態操縱菜單,配置起來十分方便;

    3,靈活的元數據;

    從數據庫表,字段級控制數據,功能十分強大;

    4,功能強大的工作流;

    方便的流程控制,管理;

    5,報表打印;

    對各類報表數據提供打印支持;

    6,系統性能監控。

    監視系統運行狀況,獲得穩定性保證。
    posted @ 2006-05-10 23:19 小馬歌 閱讀(1635) | 評論 (3)編輯 收藏
     
            不管你此刻的心情,感覺如何。請看以下最感動我的話,來之陸幼青。看后請閉上你的眼睛,反復的默念。記住是用你的意念,用心。

    “在你去過的一座遙遠的山里,向陽的山坡,

    在一段久沒有人走過的田埂,草叢中,

    在枯澀昏暗的臺燈光圈外,冷落的花盆中,

    在為典禮而忙碌的皇家園林中,精致的圣壇,

    有一些小小的,名叫做向日葵的植物在生長,

    笑臉為形,真金如色,且懂得尋找陽光。

    讓我們入靜,

    意念春光,靜享人生。。。。。。”

    我想不管我們在人生的旅途中有怎么樣的挫折和悲傷。我們都要記得我們還有最珍貴的生命。有什么樣的挫折和悲傷不可逾越呢?重要的是我們曾經經歷過,勇敢的站起來面對生活和自己。堅持到底,累了閉上眼睛,用意念用心默念以上陸幼青留給我們的話!
    posted @ 2005-06-19 11:32 小馬歌 閱讀(509) | 評論 (0)編輯 收藏
     
         摘要: 首先,要寫出自己的Ant Task是一件非常簡單的事情,有了心里的這層藐視之后,做起事來就容易多了!說說我做這個Ant Task的背景,隨著部門框架的推廣,支持國際化是一個嚴肅的問題,我們選擇了utf-8作為UNICODE字符集的編碼形式,因此現有項目必須經過一些轉換的處理,自然,Ant是首選工具。可以看一個完整的build.xml: <?xml version="1.0"...  閱讀全文
    posted @ 2005-06-16 11:01 小馬歌 閱讀(692) | 評論 (0)編輯 收藏
     
    設置header為下面的就行了,這樣就可以實現彈出下載提示框的效果。   
    response.setHeader(
        "Content-Disposition",
        "inline; filename=url");
    posted @ 2005-06-15 21:39 小馬歌 閱讀(1842) | 評論 (1)編輯 收藏
     
    1你可以不擁有任何東西,除了對生活的激情。 
    2然后是錢。 
    3努力賺錢。 
    4有了錢,可以擁有很多女人的身體。 
    5沒有錢,要擁有很多女人的心。 
    6如果身體和心你都無法得到,那只能說明你的無能。 
    7英雄和浪子,取長補短。 
    8該英雄時要英雄,該浪子時得浪子。 
    9喝酒,抽煙。一個都不能上癮。 
    10賭,女人,權力。追求,但不能沉淪。
    11熱愛體育。如果你不熱愛你就不是男人。 
    12即使你愛體育愛得發瘋。也不能抱著體育生活一輩子。 
    13善待你的家人。 
    14網絡游戲,淺嘗輒止。 
    15有分寸,懂得控制自己。 
    16廚藝精湛,但不輕易下廚。 
    17如果廚藝不佳,刀功一定要好。 
    18得到女人的心,先滿足她的胃。 
    19再給她可以倚靠的肩膀。 
    20依賴。女人的致命處。 
    21想讓女人嫁給你,給她安全感。經濟上和精神上的雙重安全。 
    22不要以為每個女人都很傻。 
    23如果不打算騙女人一生一世。就不要輕易騙她。 
    24如果是善意的謊言,要設法讓她明白你的良苦用心。 
    25如果不愛她,就不要娶她。除非你能保證對她好。 
    26如果背叛了她,就盡量補償她。 
    27女人的壽命比男人長,她會恨男人一直恨到死。 
    28最好不要得罪女人。 
    29補償最好的方式是錢。 
    30連錢都不要的女人,要小心。 
    31追到一個女人很容易,可是擺脫掉卻很難。追求之前請三思。 
    32不要跟玩不起的人玩。 
    33就算是嘗試一夜情,也不要選擇去嫖娼。 
    34對象的選擇和客戶一樣,慎重。 
    35不要輕易給女人承諾。說者無心,聽者有意。 
    36尊重女人的最好方式就是坦誠對她。 
    37即使你是個**,也要**得坦坦蕩蕩。 
    38沒有一個女人,能比你的母親重要。 
    39小時糊涂,大事不糊涂。 
    40身材魁梧,動作溫柔。 
    41找一個理解你的人做妻子。 
    42找一個了解你的女人做知已。 
    43作為成熟男人,應該清楚得不到的才是最好的。 
    所以,該舍時要舍得。 
    44不要打女人。有這種沖動前先看看《婦女權益保障法》。 
    45不要談太多次戀愛。否則你自己都會厭倦不堪。 
    46不要見一個愛一個,愛得太多,你的愛就要貶值。 
    47“我愛你”這三個字不必掛在嘴邊,用行動來證明吧。 
    48“我愛你”堵住所有廢話的最后一擊。話要用在刀刃上。 
    49擁抱或者吻。肢體語言永遠比語言更有力度。 
    50對上司,可以服從,可以抗議。就是不能卑躬屈膝。
    51買一棟房子。即使是按揭。只要你不打算當無根浪子。 
    52再買一棟。即使是借錢。用于投資。 
    53炒股。不為賺錢,只為證明自己的判斷力。 
    54即使是輸掉一棟房子,也要笑著自嘲:我不是一個輸不起的人。 
    55買車。先買二手車。如果你技術很好或者有很多錢則另當別論。 
    56哪兒摔倒,哪兒站起來再摔幾次。 
    57沒有才華,也要有氣魄。 
    58不要西裝革履,也不必著裝休閑。把襯衫扣子解掉三顆,就是一種隨意。 
    59神采飛揚,不修邊幅。 
    60穿西裝時記著把商標撕掉。 
    61笑,在任何人面前。 
    62讓你周圍的人因為你的存在而感到快樂。 
    63怕硬可以,欺軟不行。 
    64選擇婚姻,而不是婚姻選擇你。 
    65著裝整潔,不必非得把皮鞋擦得锃亮。 
    66隨意。不必往頭發上噴發膠或者定型水。 
    67看一個女人虛榮不虛榮,就剃上光頭衣冠不整地跟她一起走在大街上。注意她的表情。 
    68一支玫瑰,或者一句甜言蜜語。關鍵時候,派上用場。女人是很容易滿足的。 
    69因為需要才喜歡,還是因為喜歡才需要。分清楚。 
    70想跟女人分手時,設法讓她先提出來。
    71大智若愚。傻與不傻,先看你會不會裝傻。 
    72做一個出色的男人,先學會哄。 
    73哄上司,哄同事,哄老人,哄女人,哄孩子。 
    74如果以上你通通都能哄到,那么恭喜你,你的人生一定值得你炫耀。 
    75魅力源于實力。 
    76能讓別人跟著你走,是你的魅力所在。 
    77脾氣溫和,性格好斗。 
    78內斂。該出手時再出手。 
    79同流,但不合污。 
    80異想天開。沒有異想,何來天開? 
    81沉穩。不乏可愛。 
    82如果實在長相嚴肅,至少可以帶點兒冷幽默。 
    83有自己的立場和觀點。不一定要表明出來。 
    84說到做到。做到再說。 
    85旅游。不必期待艷遇。 
    86沉默。有些話是不必說出來的。 
    87在女人面前,永遠不要解釋,只有認錯。 
    88邀請不熟的女士吃飯,要找些天時地利的借口。 
    89像個君子,即使你不是。 
    90先賺錢,再談愛。 
    91同居。如果你享受這種習慣。 
    92享受眼前的同時,想想以后。 
    93冷靜和超然,即使是在危難時刻。裝也要裝出來。 
    94得之淡然,失之泰然。一切皆順其自然。 
    95順然自然,并不代表不去爭取。 
    96不要跟一般人一般見識,即使是特殊人也一樣。 
    97不要罵臟話。 
    98侮辱一個人最好的方式就是置之不理。侮辱,而不是責罵。 
    99認真。但不頑固。 
    100好好生活。你的生命是一次性的。
    posted @ 2005-06-15 10:04 小馬歌 閱讀(516) | 評論 (1)編輯 收藏
     

    英文源文件:http://jakarta.apache.org/velocity/user-guide.html

    目錄
    1. About this Guide
    2. What is Velocity?
    3. What can Velocity do for me?
    1. The Mud Store example
    4. Velocity Template Language (VTL): An Introduction
    5. Hello Velocity World!
    6. Comments
    7. References
    1. Variables
    2. Properties
    3. Methods
    8. Formal Reference Notation
    9. Quiet Reference Notation
    10. Getting literal
    1. Currency
    2. Escaping Valid VTL References
    11. Case Substitution
    12. Directives
    1. Set
    2. String Literals
    3. If-Else Statements
    1. Relational and Logical Operators
    4. Foreach Loops
    5. Include
    6. Parse
    7. Stop
    8. Velocimacros
    2. Escaping VTL Directives
    3. VTL: Formatting Issues
    4. Other Features and Miscellany
    1. Math
    2. Range Operator
    3. Advanced Issues: Escaping and !
    4. Velocimacro Miscellany
    5. String Concatenation
    5. Feedback
    Velocity是什么?
    Velocity是一個基于java的模板引擎(template engine)。它允許任何人僅僅簡單的使用模板語言(template language)來引用由java代碼定義的對象。
    當Velocity應用于web開發時,界面設計人員可以和java程序開發人員同步開發一個遵循MVC架構的web站點,也就是說,頁面設計人員可以只關注頁面的顯示效果,而由java程序開發人員關注業務邏輯編碼。Velocity將java代碼從web頁面中分離出來,這樣為web站點的長期維護提供了便利,同時也為我們在JSP和PHP之外又提供了一種可選的方案。
    Velocity的能力遠不止web站點開發這個領域,例如,它可以從模板(template)產生SQL和PostScript、XML,它也可以被當作一個獨立工具來產生源代碼和報告,或者作為其他系統的集成組件使用。Velocity也可以為Turbine web開發架構提供模板服務(template service)。Velocity+Turbine提供一個模板服務的方式允許一個web應用以一個真正的MVC模型進行開發。
    Velocity能為我們作什么?
    The Mud Store Example                                                  
    假設你是一家專門出售Mud的在線商店的頁面設計人員,讓我們暫且稱它為"在線MUD商店"。你們的業務很旺,客戶下了各種類型和數量的mud訂單。他們都是通過輸入用戶名和密碼后才登陸到你的網站,登陸后就允許他們查看訂單并購買更多的mud。現在,一種非常流行的mud正在打折銷售。另外有一些客戶規律性的購買另外一種也在打折但是不是很流行的Bright Red Mud,由于購買的人并不多所以它被安置在頁面的邊緣。所有用戶的信息都是被跟蹤并存放于數據庫中的,所以某天有一個問題可能會冒出來:為什么不使用velocity來使用戶更好的瀏覽他們感興趣的商品呢?
    Velocity使得web頁面的客戶化工作非常容易。作為一個web site的設計人員,你希望每個用戶登陸時都擁有自己的頁面。
    你會見了一些公司內的軟件工程師,你發現他們每個人都同意客戶應該擁有具有個性化的信息。那讓我們把軟件工程師應該作的事情發在一邊,看一看你應該作些什么吧。
    你可能在頁面內嵌套如下的VTL聲明:
    <html>
    <body>
    Hello  $customer.Name!
    <table>
    #foreach( $mud  in  $nudsOnSpecial )
        #if ( $customer.hasPurchased( $mud )  )
            <tr>
                <td>
                    $flogger.getPromo( $mud )
                <td>
            <tr>
        #end
    #end
    </table>
    Velocity Template Language(VTL):AN introduction
    VTL意味著提供最簡單、最容易并且最整潔的方式合并頁面動態內容。
    VTL使用references來在web site內嵌套動態內容,一個變量就是一種類型的reference。變量是某種類型的refreence,它可以指向java代碼中的定義,或者從當前頁面內定義的VTL statement得到值。下面是一個VTL statement的例子,它可以被嵌套到HTML代碼中:
     #set ( $a = "Velocity" )
    和所有的VTL statement一樣,這個statement以#字符開始并且包含一個directive:set。當一個在線用戶請求你的頁面時,Velocity Templating Engine將查詢整個頁面以便發現所有#字符,然后確定哪些是VTL statement,哪些不需要VTL作任何事情。
    #字符后緊跟一個directive:set時,這個set directive使用一個表達式(使用括號封閉)――一個方程式分配一個值給變量。變量被列在左邊,而它的值被列在右邊,最后他們之間使用=號分割。
    在上面的例子中,變量是$a,而它的值是Velocity。和其他的references一樣以$字符開始,而值總是以雙引號封閉。Velocity中僅有String可以被賦值給變量。
    記住以下的規則:
    使用$字符開始的references用于得到什么;使用#字符開始的directives用于作些什么。
    Hello Velocity World!
    一旦某個變量被分配了一個值,那么你就可以在HTML文件的任何地方引用它。在下面的例子中,一個值被分配給$foo變量,并在其后被引用。
     <html>
     <body>
      #set ( $foo = "Velocity" )
      Hello $foo World!
     </body>
     </html>
    上面的實現結果是在頁面上打印"Hello Velocity World!"
    為了使包含VTL directives的statement更具有可讀性,我們鼓勵你在新行開始每個VTL statement,盡管你不是必須這么作。Set directive將在后面詳細描述。
    注釋
    單行注釋:
     ## This is a single line comment.
    多行注釋:
     #*
       Thus begins a multi-line comment. Online visitors won't
       see this text because the Velocity Templating Engine will
          ignore it.
     *#
    文檔格式:
     #**
       This is a VTL comment block and
       may be used to store such information
          as the document author and versioning
       information:
       @version 5
       @author
     *#
    References
    在VTL中有三種類型的references:變量(variables)、屬性(properties)、方法(methods)。作為一個使用VTL的頁面設計者,你和你的工程師必須就references的名稱達成共識,以便你可以在你的template中使用它們。
    Everything coming to and from a reference被作為一個String對象處理。如果有一個對象$foo是一個Integer對象,那么Velocity將調用它的toString()方法將這個對象轉型為String類型。
     變量                                                                      
     格式要求同java。
     屬性                                                                      
     例子:
      $customer.Address
      $purchase.Total
    $customer.Address有兩種含義。它可以表示:查找hashtable對象customer中以Address為關鍵字的值;也可以表示調用customer對象的getAddress()方法。當你的頁面被請求時,Velocity將確定以上兩種方式選用那種,然后返回適當的值。
    方法                                                                      
    一個方法就是被定義在java中的一段代碼,并且它有完成某些有用工作的能力,例如一個執行計算和判斷條件是否成立、滿足等。方法是一個由$開始并跟隨VTL標識符組成的References,一般還包括一個VTL方法體。例如:
     $customer.getAddress()
     $purchase.getTotal()
     $page.setTitle( "My Home Page" )
     $person.setAttributes( ["Strange", "Weird", "Excited"] )
    前兩個例子$customer.getAddress()和$purchase.getTotal()看起來挺想上面的屬性$customer.Address 和 $purchase.Total。如果你覺得他們之間有某種聯系的話,那你是正確的。
    VTL屬性可以作為VTL方法的縮寫。$customer.Address屬性和使用$customer.getAddress()方法具有相同的效果。如果可能的話使用屬性的方式是比較合理的。屬性和方法的不同點在于你能夠給一個方法指定一個參數列表。
    正式reference標記
    reference的正是格式如下:
     ${mudSlinger}    變量
     ${customer.Address}  屬性
     ${purchase.getTotal()}  方法
    非正是格式更見常用,但是有時還是使用正是格式比較適合。例如:你希望通過一個變量$vice來動態的組織一個字符串。
     Jack is a $vicemaniac.
    本來變量是$vice現在卻變成了$vicemaniac,這樣Veloctiy就不知道您到底要什么了。所以,應該使用正是格式書寫
     Jack is a ${vice}maniac
    現在Velocity知道變量是$vice而不是$vicemaniac。
    Quiet reference notation
    例如:
     <input  type="text"  name="email"  value="$email" />
    當頁面的form被初始加載時,變量$email還沒有值,這時你肯定是希望它能夠顯示一個blank text來代替輸出"$email"這樣的字段。那么使用quiet reference notation就比較合適。
     <input  type="text"  name="email"  value="$!email"/>
    這樣文本框的初始值就不會是email而是空值了。
    正式和quiet格式的reference notation也可一同使用,像下面這樣:
     <input  type="text"  name="email"  value="$!{email}"/>
    Getting literal                                                             
    Velocity使用特殊字符$和#來幫助它工作,所以如果要在template里使用這些特殊字符要格外小心。本節將討論$字符。
     貨幣字符                                                                  
    在VTL中使用$2.5這樣的貨幣標識是沒有問題得的,VTL不會將它錯認為是一個reference,因為VTL中的reference總是以一個大寫或者小寫的字母開始。
    Escaping valid VTL reference                                             
    VTL中使用"\"作為逃逸符。
    例如:
     #set( $email = "foo" )
     $email
     \$email
     
    \\$email
     \\\$email
    將render為:
     foo
     $email
     \foo
     
    \\$email
    如果email變量沒有被定義則
     $email
     \$email
     
    \\$email
     \\\$email
    將被render為:
     $email
     \$email
     
    \\$email
     \\\$email
    注意:VTL中未被定義的變量將被認為是一個字符串,所以以下例子:
     #set( $foo = "gibbous" )
     $moon = $foo
    的輸出結果是:
    $moon = gibbous
    Case substitution
    現在你已經對reference比較熟悉了,你可以將他們高效的應用于你的template了。Velocity利用了很多java規范以方便了設計人員的使用。例如:
     $foo
     $foo.getBar()
     ## is the same as
     $foo.Bar

     $data.getUser("jon")
     ## is the same as
     $data.User("jon")

     $data.getRequest().getServerName()
     # is the same as
     $data.Request.ServerName
     ## is the same as
     ${data.Request.ServerName}
    但是,注意VTL中不會將reference解釋為對象的實例變量。例如:$foo.Name將被解釋為Foo對象的getName()方法,而不是Foo對象的Name實例變量。
    Directives
    Reference允許設計者使用動態的內容,而directive使得你可以應用java代碼來控制你的顯示邏輯,從而達到你所期望的顯示效果。
     #set                                                                      
     #set directive被用于設置一個reference的值。例如:
      #set ( $primate = "monkey" )
      #set ( $customer.Behavior = $primate )
    賦值左側的(LHS)必須是一個變量或者屬性reference。右側(RHS)可以是以下類型中一種:
      變量reference
      String literal
      屬性reference
      方法reference
      number literal
      ArrayList
    下面是應用各種類型的RHS的例子:
     #set ( $monkey = $bill ) ##變量reference
     #set ( $monkey.Friend = "monica" ) ##String literal
     #set ( $monkey.Blame = $whitehouse.Leak )##屬性reference
     #set ( $monkey.Plan = $spindoctor.weave($web) )##方法reference
     #set ( $monkey.Number = 123 )##Number literal
     #set ( $monkey.Say = ["Not", $my, "fault"] )##ArrayList
    注意:最后一個例子的取值方法為:$monkey.Say.get(0)
    RHS也可以是一個簡單的算術表達式:
     #set ( $value = $foo + 1 )
     #set ( $value = $bar -1 )
    #set ( $value = $foo * $bar )
    #set ( $value = $foo / $bar )
    如果你的RHS是一個null,VTL的處理將比較特殊:它將指向一個已經存在的reference,這對初學者來講可能是比較費解的。例如:
     #set ( $resut = $query.criteria("name") )
     The result of the first query is $result

     #set ( $resut = $query.criteria("address") )
     The result of the second query is $result
    如果$query.criteria("name")返回一個"bill",而$query.criteria("address")返回的是null,則顯示的結果如下:
     The result of the first query is bill
     The result of the first query is bill
    看看下面的例子:
     #set( $criteria = ["name", "address"] )
    #foreach( $criterion in $criteria )
        #set( $result = $query.criteria($criterion) )
         #if( $result )
             Query was successful
          #end
    #end
    在上面的例子中,程序將不能智能的根據$result的值決定查詢是否成功。在$result被#set后(added to the context),它不能被設置回null(removed from the context)。打印的結果將顯示兩次查詢結果都成功了,但是實際上有一個查詢是失敗的。
    為了解決以上問題我們可以通過預先定義的方式:
     #set( $criteria = ["name", "address"] )
     #foreach( $criterion in $criteria )
      #set( $result = false )
      #set( $result = $query.criteria( $criterion ) )
      #if( $result )
       Query was successful
      #end
     #end
     String Literals                                                        
     當你使用#set directive,String literal封閉在一對雙引號內。
      #set ( $directoryRoot = "www" )
      #set ( $templateName = "index.vm" )
      #set ( $template = "$directoryRoot/$tempateName" )
      $template
     上面這段代碼的輸出結果為:www/index.vm
     但是,當string literal被封裝在單引號內時,它將不被解析:
      #set ( $foo = "bar" )
      $foo
      #set ( $blargh = '$foo' )
     結果:
      bar
      $foo
     上面這個特性可以通過修改velocity.properties文件的stringliterals.interpolate = false的值來改變上面的特性是否有效。
    條件語句
     if/elseif/else                                                              
    當一個web頁面被生成時使用Velocity的#if directrive,如果條件成立的話可以在頁面內嵌入文字。例如:
     #if ( $foo )
      <strong>Velocity!</strong>
     #end
    上例中的條件語句將在以下兩種條件下成立:
      $foo是一個boolean型的變量,且它的值為true
      $foo變量的值不為null
    這里需要注意一點:Velocity context僅僅能夠包含對象,所以當我們說"boolean"時實際上代表的時一個Boolean對象。即便某個方法返回的是一個boolean值,Velocity也會利用內省機制將它轉換為一個Boolean的相同值。
    如果條件成立,那么#if和#end之間的內容將被顯示。
    #elseif和#else元素可以同#if一同使用。例如:
     #if( $foo < 10 )
      <strong> Go North </strong>
     #elseif( $foo == 10 )
      <strong> Go East </strong>
     #elseif( $foo == 6 )
      <strong> Go South </strong>
     #else
      <strong> Go West </strong>
     #end
    注意這里的Velocity的數字是作為Integer來比較的――其他類型的對象將使得條件為false,但是與java不同它使用"=="來比較兩個值,而且velocity要求等號兩邊的值類型相同。
    關系、邏輯運算符                                                          
    Velocity中使用等號操作符判斷兩個變量的關系。例如:
     #set ( $foo = "deoxyribonucleic acid" )
     #set ( $bar = "ribonucleic acid" )
     #if ( $foo == $foo )
      In this case it's clear they aren't equivalent.So…
     #else
      They are not equivalent and this will be the output.
     #end
    Velocity有AND、OR和NOT邏輯運算符。下面是一些例子:
     ## logical AND
     #if( $foo && $bar )
      <strong> This AND that </strong>
     #end

     ## logical OR
     #if ( $foo || $bar )
      <strong>This OR That </strong>
     #end

     ##logical NOT
     #if ( !$foo )
      <strong> NOT that </strong>
     #end
    循環                                                                      
     Foreach循環                                                              
     例子:
      <ul>
       #foreach ( $product in $allProducts )
        <li> $product </li>
       #end
      </ul>
     每次循環$allProducts中的一個值都會賦給$product變量。
    $allProducts可以是一個Vector、Hashtable或者Array。分配給$product的值是一個java對象,并且可以通過變量被引用。例如:如果$product是一個java的Product類,并且這個產品的名字可以通過調用他的getName()方法得到。
    現在我們假設$allProducts是一個Hashtable,如果你希望得到它的key應該像下面這樣:
     <ul>
      #foreach ( $key in $allProducts.keySet() )
       <li>Key: $key -> Value: $allProducts.get($key) </li>
      #end
     </ul>
    Velocity還特別提供了得到循環次數的方法,以便你可以像下面這樣作:
     <table>
     #foreach ( $customer in $customerList )
      <tr><td>$velocityCount</td><td>$customer.Name</td></tr>
     #end
     </table>
    $velocityCount變量的名字是Velocity默認的名字,你也可以通過修改velocity.properties文件來改變它。默認情況下,計數從"1"開始,但是你可以在velocity.properties設置它是從"1"還是從"0"開始。下面就是文件中的配置:
     # Default name of loop counter
     # variable reference
     directive.foreach.counter.name = velocityCount

     # Default starting value of the loop
     # counter variable reference
     directive.foreach.counter.initial.value = 1
    include
    #include script element允許模板設計者引入本地文件。被引入文件的內容將不會通過模板引擎被render。為了安全的原因,被引入的本地文件只能在TEMPLATE_ROOT目錄下。
     #inclued ( "one.txt" )
    如果您需要引入多個文件,可以用逗號分隔就行:
     #include ( "one.gif", "two.txt", "three.htm" )
    在括號內可以是文件名,但是更多的時候是使用變量的:
     #inclue ( "greetings.txt", $seasonalstock )
    parse
    #parse script element允許模板設計者一個包含VTL的本地文件。Velocity將解析其中的VTL并render模板。
     #parse( "me.vm" )
    就像#include,#parse接受一個變量而不是一個模板。任何由#parse指向的模板都必須包含在TEMPLATE_ROOT目錄下。與#include不同的是,#parse只能指定單個對象。
    你可以通過修改velocity.properties文件的parse_direcive.maxdepth的值來控制一個template可以包含的最多#parse的個數――默認值是10。#parse是可以遞歸調用的,例如:如果dofoo.vm包含如下行:
     Count down.
     #set ( $count = 8 )
     #parse ( "parsefoo.vm" )
     All done with dofoo.vm!
    那么在parsefoo.vm模板中,你可以包含如下VTL:
     $count
     #set ( $count = $count - 1 )
     #if ( $count > 0 )
      #parse( "parsefoo.vm" )
     #else
      All done with parsefoo.vm!
     #end
    的顯示結果為:
     Count down.
     8
     7
     6
     5
     4
     3
     2
     1
     0
     All done with parsefoo.vm!
    All done with dofoo.vm!
    Stop
    #stop script element允許模板設計者停止執行模板引擎并返回。把它應用于debug是很有幫助的。
     #stop
    Velocimacros
    #macro script element允許模板設計者定義一段可重用的VTL template。例如:
     #macro ( d )
     <tr><td></td></tr>
     #end
    在上面的例子中Velocimacro被定義為d,然后你就可以在任何VTL directive中以如下方式調用它:
     #d()
    當你的template被調用時,Velocity將用<tr><td></td></tr>替換為#d()。
    每個Velocimacro可以擁有任意數量的參數――甚至0個參數,雖然定義時可以隨意設置參數數量,但是調用這個Velocimacro時必須指定正確的參數。下面是一個擁有兩個參數的Velocimacro,一個參數是color另一個參數是array:
     #macro ( tablerows $color $somelist )
     #foreach ( $something in $somelist )
      <tr><td bgcolor=$color>$something</td</tr>
     #end
     #end
    調用#tablerows Velocimacro:
     #set ( $greatlakes = [ "Superior", "Michigan", "Huron", "Erie", "Ontario" ] )
     #set ( $color = "blue" )
     <table>
      #tablerows( $color $greatlakes )
     </table>
    經過以上的調用將產生如下的顯示結果:
     <table>
      <tr><td bgcolor=" blue"> Superior </td></tr>
      <tr><td bgcolor=" blue"> Michigan </td></tr>
      <tr><td bgcolor=" blue"> Huron </td></tr>
      <tr><td bgcolor=" blue"> Erie </td></tr>
      <tr><td bgcolor=" blue"> Ontario </td></tr>
     </table>
    Velocimacros可以在Velocity模板內實現行內定義(inline),也就意味著同一個web site內的其他Velocity模板不可以獲得Velocimacros的定義。定義一個可以被所有模板共享的Velocimacro顯然是有很多好處的:它減少了在一大堆模板中重復定義的數量、節省了工作時間、減少了出錯的幾率、保證了單點修改。
    上面定義的#tablerows( $color $list )Velocimacro被定義在一個Velocimacros模板庫(在velocity.properties中定義)里,所以這個macro可以在任何規范的模板中被調用。它可以被多次應用并且可以應用于不同的目的。例如下面的調用:
     #set ( $parts = [ "volva", "stipe", "annulus", "gills", "pileus" ] )
     #set ( $cellbgcol = "#CC00FF" )
     <table>
      #tablerows( $cellbgcol $parts )
     </table>
    上面VTL將產生如下的輸出:
     <table>
      <tr><td bgcolor="#CC00FF"> volva </td</tr>
      <tr><td bgcolor="#CC00FF"> stipe </td</tr>
      <tr><td bgcolor="#CC00FF"> annulus </td</tr>
      <tr><td bgcolor="#CC00FF"> gills </td</tr>
      <tr><td bgcolor="#CC00FF"> pileus </td</tr>
     </table>
     Velocimacro arguments                                                  
     Velocimacro可以使用以下任何元素作為參數:
      Reference:任何以$開頭的reference
      String literal:
      Number literal:
      IntegerRange:[1….3]或者[$foo….$bar]
      對象數組:["a","b","c"]
      boolean值:true、false
    當將一個reference作為參數傳遞給Velocimacro時,請注意reference作為參數時是以名字的形式傳遞的。這就意味著參數的值在每次Velocimacro內執行時才會被產生。這個特性使得你可以將一個方法調用作為參數傳遞給Velocimacro,而每次Velocimacro執行時都是通過這個方法調用產生不同的值來執行的。例如:
     #macro ( callme $a )
      $a $a $a
     #end
     #callme( $foo.bar() )
    執行的結果是:reference $foo的bar()方法被執行了三次。
    如果你不需要這樣的特性可以通過以下方法:
     #set ( $myval = $foo.bar() )
     #callme ( $myval )
    Velocimacro properties                                                  
    Velocity.properties文件中的某幾行能夠使Velocimacros的實現更加靈活。注意更多的內容可以看Developer Guide。
    Velocity.properties文件中的velocimacro.libraary:一個以逗號分隔的模板庫列表。默認情況下,velocity查找唯一的一個庫:VM_global_library.vm。你可以通過配置這個屬性來指定自己的模板庫。
    Velocity.properties文件中的velocimacro.permissions.allow.inline屬性:有兩個可選的值true或者false,通過它可以確定Velocimacros是否可以被定義在regular template內。默認值是ture――允許設計者在他們自己的模板中定義Velocimacros。
    Velocity.properties文件中的
    velocimacro.permissions.allow.inline.replace.global屬性有兩個可選值true和false,這個屬性允許使用者確定inline的Velocimacro定義是否可以替代全局Velocimacro定義(比如在velocimacro.library屬性中指定的文件內定義的Velocimacro)。默認情況下,此值為false。這樣就阻止本地Velocimacro定義覆蓋全局定義。
    Velocity.properties文件中的
    velocimacro.permissions.allow.inline.local.scale屬性也是有true和false兩個可選值,默認是false。它的作用是用于確定你inline定義的Velocimacros是否僅僅在被定義的template內可見。換句話說,如果這個屬性設置為true,一個inline定義的Velocimacros只能在定義它的template內使用。你可以使用此設置實現一個奇妙的VM敲門:a template can define a private implementation of the second VM that will be called by the first VM when invoked by that template. All other templates are unaffected。
    Velocity.properties文件中的velocimacro.context.localscope屬性有true和false兩個可選值,默認值為false。當設置為true時,任何在Velocimacro內通過#set()對context的修改被認為是針對此velocimacro的本地設置,而不會永久的影響內容。
    Velocity.properties文件中的velocimacro.library.autoreload屬性控制Velocimacro庫的自動加載。默認是false。當設置為ture時,對于一個Velocimacro的調用將自動檢查原始庫是否發生了變化,如果變化將重新加載它。這個屬性使得你可以不用重新啟動servlet容器而達到重新加載的效果,就像你使用regular模板一樣。這個屬性可以使用的前提就是resource loader緩存是off狀態(file.resource.loader.cache = false)。注意這個屬性實際上是針對開發而非產品的。
    Velocimacro Trivia                                                        
    Velocimacro必須被定義在他們被使用之前。也就是說,你的#macro()聲明應該出現在使用Velocimacros之前。
    特別要注意的是,如果你試圖#parse()一個包含#macro()的模板。因為#parse()發生在運行期,但是解析器在parsetiem決定一個看似VM元素的元素是否是一個VM元素,這樣#parse()-ing一組VM聲明將不按照預期的樣子工作。為了得到預期的結果,只需要你簡單的使用velocimacro.library使得Velocity在啟動時加載你的VMs。
    Escaping VTL directives
    VTL directives can be escaped with "\"號,使用方式跟VTL的reference使用逃逸符的格式差不多。
     ## #include( "a.txt" ) renders as <ontents of a.txt>(注釋行)
     #include( "a.txt" )

     ## \#include( "a.txt" ) renders as \#include( "a.txt" )
     \#include( "a.txt" )

     ## \\#include ( "a.txt" ) renders as \<contents of a.txt>
     
    \\#include( "a.txt" )
    在對在一個directive內包含多個script元素的VTL directives使用逃逸符時要特別小心(比如在一個if-else-end statement內)。下面是VTL的if-statement的典型應用:
     #if ( $jazz )
      Vyacheslav Ganelin
     #end
    如果$jazz是ture,輸出將是:
     Vyacheslav Ganelin
    如果$jazz是false,將沒有輸出。使用逃逸符將改變輸出。考慮一下下面的情況:
     \#if ( $jazz )
      Vyacheslav Ganelin
     \#end
    現在無論$jazz是true還是false,輸出結果都是:
     #if ( $jazz )
      Vyacheslav Ganelin
     #end
    事實上,由于你使用了逃逸符,$jazz根本就沒有被解析為boolean型值。在逃逸符前使用逃逸符是合法的,例如:
     
    \\#if ( $jazz )
      Vyacheslav Ganelin
     
    \\#end
    以上程序的顯示結果為:
     \ Vyacheslav Ganelin
     \
    但是如果$jazz為false,那么將沒有輸出。(書上說會沒有輸出,但是我覺得應該還有有"\"字符被輸出。)
    VTL:Formatting issues
    盡管在此用戶手冊中VTL通常都開始一個新行,如下所示:
     #set ( $imperial = [ "Munetaka", "Koreyasu", "Hisakira", "Morikune" ] )
     #foreach ( $shogun in $imperial )
      $shogun
     #end
    但是像下面這種寫法也是可以的:
     Send me #set($foo = ["$10 and","a cake"])#foreach($a in $foo)$a #end please.
    上面的代碼可以被改寫為:
     Send me
     #set ( $foo = ["$10 and ","a cake"] )
     #foreach ( $a in $foo )
      $a
     #end
     please.
    或者
     Send me
     #set($foo      = ["$10 and ","a cake"])
        #foreach         ($a in $foo )$a
       #end please.
    這兩種的輸出結構將一樣。
    其他特性和雜項
     math                                                                       在模板中可以使用Velocity內建的算術函數,如:加、減、乘、除
      #set ( $foo = $bar + 3 )
      #set ( $foo = $bar - 4 )
      #set ( $foo = $bar * 6 )
      #set ( $foo = $bar / 2 )
     當執行除法時將返回一個Integer類型的結果。而余數你可以使用%來得到:
      #set ( $foo = $bar % 5 )
    在Velocity內使用數學計算公式時,只能使用像-n,-2,-1,0,1,2,n這樣的整數,而不能使用其它類型數據。當一個非整型的對象被使用時它將被logged并且將以null作為輸出結果。
    Range Operator
    Range operator可以被用于與#set和#foreach statement聯合使用。對于處理一個整型數組它是很有用的,Range operator具有以下構造形式:
     [n..m]
    m和n都必須是整型,而m是否大于n則無關緊要。例子:
     First example:
     #foreach ( $foo in [1..5] )
      $foo
     #end

     Second example:
     #foreach ( $bar in [2..-2] )
      $bar
     #end

     Third example:
     #set ( $arr = [0..1] )
     #foreach ( $i in $arr )
      $i
     #end

     Fourth example:
     [1..3]
    上面四個例子的輸出結果為:
     First example:
     1 2 3 4 5

     Second example:
     2 1 0 -1 -2

     Third example:
     0 1

     Fourth example:
     [1..3]
    注意:range operator只在#set和#foreach中有效。
    Advanced Issue:Escaping and!
    當一個reference被"!"分隔時,并且在它之前有逃逸符時,reference將以特殊的方式處理。注意這種方式與標準的逃逸方式時不同的。對照如下:
    #set ( $foo = "bar" )
    特殊形式 標準格式
    Render前 Render后 Render前 Render后
    $\!foo $!foo \$foo \$foo
    $\!{foo} $!{foo} \$!foo \$!foo
    $\\!foo $\!foo \$!{foo} \$!{foo}
    $\\\!foo $\\!foo 
    \\$!{foo} \bar
    Velocimacro雜記
     Can I user a directive or another VM as an argument to a VM?     
     例如:#center ( #bold( "hello" ) )
     不可以。一個directive的參數使用另外一個directive是不合法的。
     但是,還是有些事情你可以作的。最簡單的方式就是使用雙引號:
      #set ( $stuff = "#bold( 'hello' )" )
      #center ( $stuff )
     上面的格式也可以縮寫為一行:
      #center ( "#bold( 'hello' ) )
    請注意在下面的例子中參數被evaluated在Velocimacro內部,而不是在calling level。例子:
     #macro ( inner $foo )
      inner : $foo
     #end

     #macro ( outer $foo )
      #set ( $bar = "outerlala" )
      outer : $foo
     #end
     
     #set ( $bar = 'calltimelala' )
     #outer( "#inner($bar)" )
    輸出結果為:
     outer : inner : outerlala
    記住Veloctiy的特性:參數的傳遞是By Name的。例如:
     #macro ( foo $color )
      <tr bgcolor = $color ><td>Hi</td></tr>
      <tr bgcolor = $color ><td>There</td></tr>
     #end

     #foo ( $bar.rowColor() )
    以上代碼將導致rowColor()方法兩次調用,而不是一次。為了避免這種現象的出現,我們可以按照下面的方式執行:
     #set ( $color = $bar.rowColor() )
     #foo ( $color )
    can I register velocimacros via #parse()?                                
    目前,Velocimacros必須在第一次被模板調用前被定義。這就意味著你的#macro()聲明應該出現在使用Velocimacros之前。
    如果你試圖#parse()一個包含#macro() directive的模板,這一點是需要牢記的。因為#parse()發生在運行期,但是解析器在parsetiem決定一個看似VM元素的元素是否是一個VM元素,這樣#parse()-ing一組VM聲明將不按照預期的樣子工作。為了得到預期的結果,只需要你簡單的使用velocimacro.library使得Velocity在啟動時加載你的VMs。
    What is velocimacro autoreloading?                                      
    velocimacro.library.autoreload是專門為開發而非產品使用的一個屬性。此屬性的默認值是false。
    String concatenation
    開發人員最常問的問題是我如何作字符拼接?在java中是使用"+"號來完成的。
    在VTL里要想實現同樣的功能你只需要將需要聯合的reference放到一起就行了。例如:
    #set ( $size = "Big" )
    #set ( $name = "Ben" )
    The clock is $size$name.
    輸出結果將是:The clock is BigBen.。更有趣的情況是:
     #set ( $size = "Big" )
     #set ( $name = "Ben" )
     #set ( $clokc = "$size$name" )
     The clock is $clock.
    上例也會得到同樣的結果。最后一個例子,當你希望混合固定字段到你的reference時,你需要使用標準格式:
     #set ( $size = "Big" )
     #set ( $name = "Ben" )
     #set ( $clock = "${size}Tall$name" )
     The clock is $clock.
    輸出結果是:The clock is BigTallBen.。使用這種格式主要是為了使得$size不被解釋為$sizeTall。
    反饋

     

    posted @ 2005-06-14 22:50 小馬歌 閱讀(449) | 評論 (0)編輯 收藏
     
         摘要:   第一章 XML的發展背景     XML是W3C在1996年底提出的標準,是從SGML衍生出來的簡化格式,也是一種元語言(meta-language),可以用來定義任何一種新的標示語言。XML的制定是為了補HTML的不足,使得在Web上能夠傳輸、處理各類復雜的文件,它舍去了SGML復雜不常用及不利于在Web傳送的選項功能,讓使用者可以很容易地定義屬于...  閱讀全文
    posted @ 2005-06-14 22:39 小馬歌 閱讀(2716) | 評論 (1)編輯 收藏
     

    1.Velocity 的使用

    Velocity是一個開放源碼的模版引擎,由apache.org小組負責開發,現在最新的版本是Velocity1.4,
    http://jakarta.apache.org/velocity/index.html 可以了解Velocity的最新信息。
    Velocity允許我們在模版中設定變量,然后在運行時,動態的將數據插入到模版中,替換這些變量。
    例如:
    <html>
    <body>HELLO $CUSTOMERNAME</body>
    </html>
    我們可以在運行時得到客戶的名字,然后把它插入到這個模版中替換變量$CUSTOMERNAME,整個替換過程是由Velocity進行控制的,而且java的調用代碼也非常簡單,如我們可以在java代碼中這樣調用

    /***********************************************************/ 
    //這個文件中設定了Velocity使用的log4j的配置和Velocity的模版文件所在的目錄 
    Velocity.init("D:\\Template\\resource\\jt.properties"); 
    //模版文件名,模版文件所在的路徑在上一條語句中已經設置了 
    Template template = Velocity.getTemplate("hello.vm""gb2312"); 
    //實例化一個Context 
    VelocityContext context = new VelocityContext(); 
    //把模版變量的值設置到context中 
    context.put("CUSTOMERNAME""My First Template Engine ---- Velocity."); 
    //開始模版的替換 
    template.merge(context, writer); 
    //寫到文件中 
    PrintWriter filewriter = new PrintWriter(new FileOutputStream(outpath),true); 
    filewriter.println(writer.toString()); 
    filewriter.close(); 
    /***********************************************************/ 


    這就是整個java的代碼,非常的簡單。如果我們有多個模版變量,我們僅需要把這些模版變量的值設置到context中。
    下面我們簡單的分析一下,Velocity引擎讀取模板文件時,它直接輸出文件中所有的文本,但以$字符開頭的除外,$符號標識著一個模版變量位置,
    context.put("CUSTOMERNAME", "My First Template Engine ---- Velocity.");
    當 Velocity 模板引擎解析并輸出模板的結果時,模板中所有出現$CUSTOMERNAME的地方都將插入客戶的名字,即被加入到VelocityContext的對象的toString()方法返回值將替代Velocity變量(模板中以$開頭的變量)。
    模板引擎中最強大、使用最頻繁的功能之一是它通過內建的映像(Reflection)引擎查找對象信息的能力。這個映像引擎允許用一種方便的Java“.”類似的操作符,提取任意加入到VelocityContext的對象的任何公用方法的值,或對象的任意數據成員。
    映像引擎還帶來了另外一個改進:快速引用JavaBean的屬性。使用JavaBean屬性的時候,我們可以忽略get方法和括號。請看下面這個模板的例子。
    <html>
    <body>
    Name:$Customer.Name()
    Address:$Customer.Address()
    Age:$Customer.Age()
    </body>
    </html>

    java的代碼:

    /***********************************************************/ 
    //設置客戶信息 
    Customer mycustomer = new Customer(); 
    mycustomer.setName(
    "Velocity"); 
    mycustomer.setAddress(
    "jakarta.apache.org/velocity/index.html"); 
    mycustomer.setAge(
    2); 
    //這個文件中設定了 Velocity 使用的 Log4j 的配置和Velocity的模版文件所在的目錄Velocity.init("D:\\Template\\resource\\jt.properties"); 
    //模版文件名,模版文件所在的路徑在上一條語句中已經設置了 
    Template template = Velocity.getTemplate("hello.vm""gb2312"); 
    //實例化一個Context 
    VelocityContext context = new VelocityContext(); 
    //把模版變量的值設置到context中 
    context.put("Customer", mycustomer); 
    //開始模版的替換 
    template.merge(context, writer); 
    //寫到文件中 
    PrintWriter filewriter = new PrintWriter(new FileOutputStream(outpath),true); 
    filewriter.println(writer.toString()); 
    filewriter.close(); 

    輸出結果:
    <html>
    <body>
    Name:Velocity
    Address:jakarta.apache.org/velocity/index.html
    Age:2
    </body>
    </html>
    除了替換變量之外,象Velocity高級引擎還能做其他許多事情,它們有用來比較和迭代的內建指令,通過這些指令我們可以完成程序語言中的條件判斷語句和循環語句等。
    例如,我們想要輸出年齡等于2的所有客戶的信息,我們可以這樣定義我們的模版
    模版:
    <html>
    <body>
    <table>
    <tr>
    <td>名稱</td>
    <td>地址</td>
    <td>年齡</td>
    </tr>
    #foreach ($Customer in $allCustomer)
    #if($Customer.Age()=="2")
    <tr>
    <td>$Customer.Name()</td>
    <td>$Customer.Address()</td>
    <td>$Customer.Age()</td>
    </tr>
    #end
    #end
    </table>
    </body>
    </html>

    java的代碼:
     

    /******************************************************/ 
    //設置客戶信息 
    ArrayList allMyCustomer = new ArrayList(); 
    //客戶1 
    Customer mycustomer1 = new Customer(); 
    mycustomer1.setName(
    "Velocity"); 
    mycustomer1.setAddress(
    "jakarta.apache.org/velocity/index.html"); 
    mycustomer1.setAge(
    2); 
    //客戶2 
    Customer mycustomer2 = new Customer(); 
    mycustomer2.setName(
    "Tomcat"); 
    mycustomer2.setAddress(
    "jakarta.apache.org/tomcat/index.html"); 
    mycustomer2.setAge(
    3); 
    //客戶3 
    Customer mycustomer3 = new Customer(); 
    mycustomer3.setName(
    "Log4J"); 
    mycustomer3.setAddress(
    "jakarta.apache.org/log4j/docs/index.html"); 
    mycustomer3.setAge(
    2); 
    //添加到allMyCustomer(ArrayList)中. 
    allMyCustomer.add(mycustomer1); 
    allMyCustomer.add(mycustomer2); 
    allMyCustomer.add(mycustomer3); 
    //這個文件中設定了Velocity使用的log4j的配置和Velocity的模版文件所在的目 
    Velocity.init("D:\\Template\\resource\\jt.properties"); 
    //模版文件名,模版文件所在的路徑在上一條語句中已經設置了 
    Template template =Velocity.getTemplate("hello.vm""gb2312"); 
    //實例化一個Context 
    VelocityContext context = new VelocityContext(); 
    /** 注意這里我們僅僅需要給一個模版變量負值 */ 
    context.put(
    "allCustomer", allMyCustomer); 
    //開始模版的替換 
    template.merge(context, writer); 
    //寫到文件中 
    PrintWriter filewriter = new PrintWriter(new FileOutputStream(outpath),true); 
    filewriter.println(writer.toString()); 
    filewriter.close(); 
    /******************************************************/ 

    結果:
    <html>
    <body>
    <table>
    <tr>
    <td>名稱</td>
    <td>地址</td>
    <td>年齡</td>
    </tr>
    <tr>
    <td>Velocity</td>
    <td>jakarta.apache.org/velocity/index.html</td>
    <td>2</td>
    </tr>
    <tr>
    <td>Log4J</td>
    <td>jakarta.apache.org/log4j/docs/index.html</td>
    <td>2</td>
    </tr>
    </table>
    </body>
    </html>

    #if 語句完成邏輯判斷,這個我想不用多說了。
    allCustomer對象包含零個或者多個Customer對象。由于ArrayList (List, HashMap, HashTable, Iterator, Vector等)屬于Java Collections Framework的一部分,我們可以用#foreach指令迭代其內容。我們不用擔心如何定型對象的類型——映像引擎會為我們完成這個任務。#foreach指令的一般格式是“#foreach in ”。#foreach指令迭代list,把list中的每個元素放入item參數,然后解析#foreach塊內的內容。對于list內的每個元素,#foreach塊的內容都會重復解析一次。從效果上看,它相當于告訴模板引擎說:“把list中的每一個元素依次放入item變量,每次放入一個元素,輸出一次#foreach塊的內容”。

    2.MVC設計模型

    使用模板引擎最大的好處在于,它分離了代碼(或程序邏輯)和表現(輸出)。由于這種分離,你可以修改程序邏輯而不必擔心郵件消息本身;類似地,你(或公關部門的職員)可以在不重新編譯程序的情況下,重新編寫客戶列表。實際上,我們分離了系統的數據模式(Data Model,即提供數據的類)、控制器(Controller,即客戶列表程序)以及視圖(View,即模板)。這種三層體系稱為Model-View-Controller模型(MVC)。
    如果遵從MVC模型,代碼分成三個截然不同的層,簡化了軟件開發過程中所有相關人員的工作。
    結合模板引擎使用的數據模式可以是任何Java對象,最好是使用Java Collection Framework的對象。控制器只要了解模板的環境(如VelocityContext),一般這種環境都很容易使用。
    一些關系數據庫的“對象-關系”映射工具能夠和模板引擎很好地協同,簡化JDBC操作;對于EJB,情形也類似。 模板引擎與MVC中視圖這一部分的關系更為密切。模板語言的功能很豐富、強大,足以處理所有必需的視圖功能,同時它往往很簡單,不熟悉編程的人也可以使用它。模板語言不僅使得設計者從過于復雜的編程環境中解脫出來,而且它保護了系統,避免了有意或無意帶來危險的代碼。例如,模板的編寫者不可能編寫出導致無限循環的代碼,或侵占大量內存的代碼。不要輕估這些安全機制的價值;大多數模板編寫者不懂得編程,從長遠來看,避免他們接觸復雜的編程環境相當于節省了你自己的時間。 許多模板引擎的用戶相信,在采用模板引擎的方案中,控制器部分和視圖部分的明確分離,再加上模板引擎固有的安全機制,使得模板引擎足以成為其他內容發布系統(比如JSP)的替代方案。因此,Java模板引擎最常見的用途是替代JSP也就不足為奇了。

    3.HTML處理

    由于人們總是看重模板引擎用來替換JSP的作用,有時他們會忘記模板還有更廣泛的用途。到目前為止,模板引擎最常見的用途是處理HTML Web內容。但我還用模板引擎生成過SQL、email、XML甚至Java源代碼。

    posted @ 2005-06-13 15:57 小馬歌 閱讀(478) | 評論 (1)編輯 收藏
     

    一般來說,ResourceBundle類通常是用于針對不同的語言來使用的屬性文件。

    而如果你的應用程序中的屬性文件只是一些配置,并不是針對多國語言的目的。那么使用Properties類就可以了。

    通常可以把這些屬性文件放在某個jar文件中。然后,通過調用class的getResourceAsStream方法,來獲得該屬性文件的流對象,再用Properties類的load方法來裝載。

    示例如下:

    Class TestLoad {
               
    public static void main( String[] argv) {
                         InputStream 
    is = TestLoad.class.getResourceAsSteam("myprops.properties");
                         Properties p 
    = new Properties();
                         p.load(
    is);
                         System.
    out.println(p.get("MAIL_SERVER_HOSTNAME"));
               }

    }

    有時候有些簡單的配置文件可以沒必要使用xml,其實ResourceBundle類就已經做的很好的。它甚至可以搜索到classpath里的jar文件中一些properties文件。

    例如在jar文件中的根目錄放置一個文件:test.properties,然后只要這個jar文件在classpath里。就可以使用這樣的語句來獲得一些屬性:

      ResourceBundle rb = ResourceBundle.getBundle("test");
      String s = rb.getString("MQ_Server_Address");
      System.out.println(s);

    posted @ 2005-06-08 19:15 小馬歌 閱讀(6170) | 評論 (0)編輯 收藏
     
    ##數據庫和表空間恢復
    #數據庫恢復

    下面是 RESTORE 命令的語法:


    RESTORE DATABASE source-database-alias { restore-options | CONTINUE | ABORT }

    restore-options:
      [USER username [USING password]] [{TABLESPACE [ONLINE] |
      TABLESPACE (tblspace-name [ {,tblspace-name} ... ]) [ONLINE] |
      HISTORY FILE [ONLINE]}] [INCREMENTAL [AUTOMATIC | ABORT]]
      [{USE {TSM | XBSA} [OPEN num-sess SESSIONS] |
      FROM dir/dev [ {,dir/dev} ... ] | LOAD shared-lib
      [OPEN num-sess SESSIONS]}] [TAKEN AT date-time] [TO target-directory]
      [INTO target-database-alias] [NEWLOGPATH directory]
      [WITH num-buff BUFFERS] [BUFFER buffer-size]
      [DLREPORT file-name] [REPLACE EXISTING] [REDIRECT] [PARALLELISM n]
      [WITHOUT ROLLING FORWARD] [WITHOUT DATALINK] [WITHOUT PROMPTING]


    讓我們研究一個示例。要執行 sample 數據庫的恢復,請使用以下命令:


    (1)RESTORE DATABASE sample
    (2)  FROM  C:\DBBACKUP
    (3)  TAKEN AT 20030314131259
    (4)  WITHOUT ROLLING FORWARD
    (5)  WITHOUT PROMPTING


    讓我們更仔細地研究該命令:

    指明要恢復的數據庫映像的名稱。
    指定要從什么位置讀取輸入備份文件。
    如果目錄中有多個備份映像,那么該選項將根據時間戳記(它是備份名稱的一部分)確定特定的備份。
    如果為數據庫啟用了歸檔日志記錄,那么當恢復該數據庫時,它將自動被置于前滾暫掛狀態。這行告訴 DB2 不要使數據庫處于前滾暫掛狀態。
    在執行 RESTORE 時,不會提示您。
    請注意,語法中沒有關鍵字 OFFLINE,因為這是缺省方式。事實上,對于 RESTORE 實用程序,這是數據庫允許的唯一方式。

    #表空間恢復

    表空間恢復需要相當仔細的規劃,因為比較容易犯錯,這會使數據處于不一致狀態。

    下面是表空間 RESTORE 命令的示例:


    (1)RESTORE DATABASE sample
    (2)  TABLESPACE ( mytblspace1 )
    (3)  ONLINE
    (4)  FROM /db2tbsp/backup1, /db2tbsp/backup2


    讓我們更仔細地研究該命令:

    指明要恢復的數據庫映像的名稱。
    指出這是表空間 RESTORE,并指定要恢復的一個或多個表空間的名稱。
    指出這是聯機恢復。注:對于用戶表空間,既允許聯機恢復也允許脫機恢復。正如前面所提到的那樣,對于數據庫,只允許脫機恢復。
    指定輸入備份文件所在的位置。
    表空間恢復注意事項

    恢復表空間之后,它將始終處于前滾暫掛狀態。要使表空間可訪問并復位該狀態,必須至少將表空間前滾到最小的時間點
    (point in time,PIT)。該最小的 PIT 確保表空間和日志與系統目錄中的內容保持一致。

    請考慮下面的示例:

    假設在時間 t1 您執行了完全數據庫備份,該備份包括了表空間 mytbls1
    在時間 t2,您在表空間 mytbls1 中創建了表 myTable。這會將表空間 mytbs1 恢復的最小 PIT 設置為 t2。
    在時間 t3,您決定僅從在 t1 進行的完全數據庫備份恢復表空間 mytbls1。
    恢復完成之后,表空間 mytbls1 將處于前滾暫掛狀態。如果允許前滾到最小 PIT 之前的某一點,則表空間 mytbls1 將失去表 myTable;然而,系統目錄將顯示該表確實存在于 mytbls1 中。因此,為了避免類似的不一致,DB2 會在您恢復表空間時強制您至少前滾到最小 PIT。
    當針對表空間或表空間中的表運行 DDL 語句時,會更新最小的 PIT。為了確定表空間恢復的最小 PIT,可以使用下列兩種方法之一:

    使用 LIST TABLESPACES SHOW DETAIL 命令
    通過 GET SNAPSHOT FOR TABLESPACE ON db_name 命令獲取表空間快照。
    另外,系統目錄表空間(SYSCATSPACE)必須前滾到日志的末尾并處于脫機方式。

    #重定向恢復
    我們前面提到過備份文件包括有關表空間和容器的信息。如果過去存在的容器在進行備份時不再存在時,會發生什么情況?如果 RESTORE 實用程序找不到該容器,那么您將得到一個錯誤。

    如果您不想在這個位置恢復該備份,而想在別的位置進行恢復,但在那個地方又使用了其它配置,該怎么辦?同樣,在該情況下恢復備份將會產生問題。

    重定向恢復解決了這些問題。重定向恢復的恢復備份過程只有四個步驟:

    獲取記錄在輸入備份中的、有關容器和表空間的信息。通過將 REDIRECT 關鍵字包含在 RESTORE 命令中就能完成這一任務。例如:

    RESTORE DATABASE DB2CERT FROM C:\DBBACKUP
            INTO NEWDB REDIRECT WITHOUT ROLLING FORWARD

    不需要事先產生數據庫NEWDB
    下面是該命令的輸出:


    SQL1277N  Restore has detected that one or more table space containers are
    inaccessible, or has set their state to 'storage must be defined'.
    DB20000I  The RESTORE DATABASE command completed successfully.

    注意:此時已經創建了數據庫NEWDB。

    復查來自(部分)恢復數據庫 newdb 的表空間信息:

    LIST TABLESPACES SHOW DETAIL
    表空間還沒有產生。

    為每個表空間設置新容器。表空間有一個標識,可以從 LIST TABLESPACES 命令的輸出獲取這個標識。如下使用該標識:

    SET TABLESPACE CONTAINERS FOR 0 USING (FILE "d:\newdb\cat0.dat" 5000)
    SET TABLESPACE CONTAINERS FOR 1 USING (FILE "d:\newdb\cat1.dat" 5000)
    ...
    SET TABLESPACE CONTAINERS FOR n USING (PATH "d:\newdb2")

    上面命令將產生表空間。

    在上面的示例中,n 表示備份中某一個表空間的標識。另外請注意,對于重定向恢復,不能更改表空間的類型;即,如果表空間是 SMS,那么就不能將它更改為 DMS。

    通過將關鍵字 CONTINUE 包含在 RESTORE 命令中,開始將數據本身恢復到新容器中,如下所示:

    RESTORE DATABASE DB2CERT CONTINUE
    現在,您已經了解了重定向恢復是如何工作的。也可以將它用于為 SMS 表空間添加容器。如果您閱讀過本系列的第二篇教程,那么您應該知道在大多數情況下不能對 SMS 表空間進行修改以添加容器。重定向恢復為這一限制提供了一種變通方法。

    分區數據庫的恢復::

    In the following example, the database WSDB is defined on all 4 partitions,
    numbered 0 through 3. The path /dev3/backup is accessible from all
    partitions. The following offline backup images are available from
    /dev3/backup:
    wsdb.0.db2inst1.NODE0000.CATN0000.20020331234149.001
    wsdb.0.db2inst1.NODE0001.CATN0000.20020331234427.001
    wsdb.0.db2inst1.NODE0002.CATN0000.20020331234828.001
    wsdb.0.db2inst1.NODE0003.CATN0000.20020331235235.001
    To restore the catalog partition first, then all other database partitions of the
    WSDB database from the /dev3/backup directory, issue the following
    commands from one of the database partitions:

    db2_all ’<<+0< db2 RESTORE DATABASE wsdb FROM /dev3/backup
    TAKEN AT 20020331234149
    INTO wsdb REPLACE EXISTING’
    db2_all ’<<+1< db2 RESTORE DATABASE wsdb FROM /dev3/backup
    TAKEN AT 20020331234427
    INTO wsdb REPLACE EXISTING’
    db2_all ’<<+2< db2 RESTORE DATABASE wsdb FROM /dev3/backup
    TAKEN AT 20020331234828
    INTO wsdb REPLACE EXISTING’
    db2_all ’<<+3< db2 RESTORE DATABASE wsdb FROM /dev3/backup
    TAKEN AT 20020331235235
    INTO wsdb REPLACE EXISTING’


    ##數據庫和表空間前滾
    #數據庫前滾
    在上一章中,我們簡要地討論了 ROLLFORWARD 命令。在本章中,我們將更詳細地討論它。ROLLFORWARD 命令允許恢復到某一時間點;
    這意味著該命令將讓您遍歷 DB2 日志,并重做或撤銷記錄在日志中的操作直到某個特定的時間點。雖然可以將數據庫或表空間前滾到最小
    PIT 之后的任何時間點,但不能保證您選擇前滾到的結束時間將使所有數據保持一致。

    我們將不在本教程中討論 QUIESCE 命令。然而,值得提一下的是:可以在常規數據庫操作期間使用該命令來設置一致性點。通過設置
    這些一致性點,您可以始終執行至其中任何一點的時間點恢復,并保證數據同步。

    一致性點和許多其它信息一起被記錄在 DB2 歷史記錄文件中,可以使用 LIST HISTORY 命令來查看該文件。

    在前滾處理期間,DB2 將:

    在當前日志路徑中查找必需的日志文件。
    如果找到該日志,重新從日志文件應用事務。
    如果在當前路徑中找不到該日志文件,并且使用了 OVERFLOWLOGPATH 選項,那么 DB2 將在該選項指定的路徑中搜索并且將使用該位置中的
    日志。
    如果在當前路徑中找不到該日志文件并且沒有使用 OVERFLOWLOGPATH 選項,則調用用戶出口來檢索歸檔路徑中的日志文件。
    僅當前滾完全數據庫恢復并且啟用了用戶出口時,才會調用用戶出口來檢索日志文件。
    一旦日志在當前日志路徑或 OVERFLOWLOGPATH 中,就將重新應用事務。
    執行 ROLLFORWARD 命令需要 SYSADM、SYSCTRL 或 SYSMAINT 權限。

    下面是 ROLLFORWARD 命令的語法:


    ROLLFORWARD DATABASE database-alias [USER username [USING password]]
    [TO {isotime [ON ALL DBPARTITIONNUMS] [USING LOCAL TIME] | END OF LOGS
    [On-DbPartitionNum-Clause]}] [AND {COMPLETE | STOP}] |
    {COMPLETE | STOP | CANCEL | QUERY STATUS [USING LOCAL TIME]}
    [On-DbPartitionNum-Clause] [TABLESPACE ONLINE | TABLESPACE (tblspace-name
    [ {,tblspace-name} ... ]) [ONLINE]] [OVERFLOW LOG PATH (log-directory
    [{,log-directory ON DBPARTITIONNUM db-partition-number} ... ])] [NORETRIEVE]
    [RECOVER DROPPED TABLE dropped-table-id TO export-directory]

    On-DbPartitionNum-Clause:
      ON {{DBPARTITIONNUM | DBPARTITIONNUMS} (db-partition-number
      [TO  db-partition-number] , ... ) | ALL DBPARTITIONNUMS [EXCEPT
      {DBPARTITIONNUM | DBPARTITIONNUMS} (db-partition-number
      [TO db-partition-number] , ...)]}


    讓我們研究一個示例。要執行樣本數據庫的前滾,可以使用下列任意一條語句:


    (1)ROLLFORWARD DATABASE sample TO END OF LOGS AND COMPLETE
    (2)ROLLFORWARD DATABASE sample TO timestamp AND COMPLETE
    (3)ROLLFORWARD DATABASE sample TO timestamp USING LOCAL TIME AND COMPLETE


    讓我們仔細地研究每一條語句:

    在該示例中,我們將前滾到日志的結尾,這意味著將遍歷所有歸檔和活動日志。最終它將完成前滾并通過回滾任何未提交的事務來除去
    前滾暫掛狀態。
    對于該示例,DB2 將前滾到指定的時間點。使用的時間戳記形式必須是 CUT(全球標準時間,Coordinated Universal Time),這可以通
    過從當前時區減去本地時間來計算。
    該示例類似于上一個示例,但可以用本地時間表示時間戳記。
    請注意,語法中沒有關鍵字 OFFLINE,因為這是缺省方式。事實上,對于 ROLLFORWARD 命令,這是數據庫允許的唯一方式。

    #表空間前滾 第 2 頁(共4 頁)


    表空間前滾通常可以聯機或脫機。但系統目錄表空間(SYSCATSPACE)是例外,它只能進行脫機前滾。

    下面是一個表空間前滾示例:

    ROLLFORWARD DATABASE sample
      TO END OF LOGS AND COMPLETE
      TABLESPACE ( userspace1 ) ONLINE


    上面示例中的選項已經在數據庫前滾一章中說明過了。這里唯一的新選項是 TABLESPACE,它指定要前滾的表空間。

    表空間前滾考慮事項

    如果啟用注冊表變量 DB2_COLLECT_TS_REC_INFO,則只處理恢復表空間所需的日志文件;ROLLFORWARD 命令將跳過不需要的日志文件,這可以加快恢復時間。
    ROLLFORWARD 命令的 QUERY STATUS 選項可用于列出 DB2 已經前滾的日志文件、下一個需要的歸檔日志文件以及自前滾處理開始以來最后一次提交的事務的時間戳記。例如:
    ROLLFORWARD DATABASE sample QUERY STATUS USING LOCAL TIME
    在表空間時間點前滾操作完成后,表空間處于備份暫掛狀態。必須對表空間或數據庫進行備份,因為在表空間恢復到的時間點和當前時間之間對它所做的所有更新都已經丟失。

    ##索引的重新創建
    #重建索引

    如果由于一些硬件或操作系統原因而使數據庫崩潰,那么在數據庫重新啟動階段一些索引可能被標記為無效。配置參數 INDEXREC 確定 DB2 何時將試圖重建無效索引。

    INDEXREC 在數據庫管理器和數據庫配置文件中都進行了定義。該參數有三個可能的設置:

    SYSTEM:只能在數據庫配置文件中指定該值。當將 INDEXREC 設置為該值時,DB2 將查找在數據庫管理器配置文件中指定的 INDEXREC 設置,并使用該值。
    ACCESS:這意味著在第一次訪問索引時重建無效索引。
    RESTART:這意味著在數據庫重新啟動期間重建無效索引。


    ###管理服務器
    get admin cfg
    update admin cfg using <p> <v>


    備份表空間
    BACKUP DATABASE SAMPLE TABLESPACE ( USERSPACE1 ) ONLINE TO "d:\db2\" WITH 1 BUFFERS BUFFER 1024 PARALLELISM 1 WITHOUT PROMPTING;

    生成表的DDL
    db2look -d SAMPLE -t  MY_EMPLOYEE  -a -e  -l  -x  -c ;
    包括表的統計信息的DDL
    db2look -d SAMPLE -t  MY_EMPLOYEE  -a -e  -l  -x  -m  -r  -c ;

    svmon

    5.1 maintrcie 4
    db2 fixpak 2

    ## 數據庫空間需求
    # 系統目錄表的空間需求  3.5MB

    # 用戶表數據的空間需求
    每頁面255行 
    4KB頁面 68字節用于管理開銷,4028用于數據,行長度不能超過4005字節,最多500列。
    8,16,32KB 頁面                                     8101,16293,32677     1012列
           估計大小公式4KB:
              (4028/(AVERAGE ROW SIZE + 10)) = RECORDS_PER_PAGE
              (NUMBER_OF_RECORDS/RECORDS_PER_PAGE)*1.1 = NUMBER_OF_PAGES
      長型字段數據的空間需求
    存儲在單獨的表對象中。數據存儲在大小為32KB的區域中。
      大對象數據的空間需求
    #索引的空間的需求
    (平均索引鍵大小+9)×行數×2
      創建索引的臨時空間需求
             (平均索引鍵大小+9)×行數×3.2
    對每個葉子頁的平均鍵數的粗略估計是
    #日志文件的空間需求
    (logprimary + logsecond)*(logfilesiz+2)*4096
    如果以對數據庫啟用了無限記錄(logsecond 設置為-1),則必須啟用userexit配置參數。
    #臨時空間需求
     
    ##分區數據庫驗證
      select distinct dbpartitionnum(empno) from employee;
    #分區鍵
    未指定則使用主鍵的第一列,無主鍵則使用第一個非長類型列。
    選擇能否使數據分布均勻及經常使用的列,可以用列的組合但不能超過16列,列越少,性能越好。
    分區鍵不能更改,任何唯一鍵或主鍵必須包含分區鍵列

    #表并置
    需要經常進行關聯的表在指定分區鍵時,每個分區鍵中對應列的數據類型必須是分區兼容的,并稱為表并置
    具有相同值但有不同類型的兩個變量會安相同的分區算法映射至同一個分區號。
            如:INTEGER,SMALLINT,BIGINT
        REAL,FLOAT
        CHAR,VARCHAR

    #隔離級別
      隔離級確定了在數據被訪問時,如何鎖定數據或將數據與其它進程隔離。您可以在應用程序預編譯或在
      靜態 SQL 程序中綁定到數據庫時指定隔離級,或者也可以將它指定為連接或語句選項。
      選擇的隔離級可同時影響 DB2 選擇的鎖定策略和 S 行鎖定可以由應用程序持有的時間。
      隔離級只應用于被讀取的行。對于更改的行,應用程序需要獲取一個 X 或 W 鎖。無論應用程序的隔離級是什么,
      X 或 W 鎖在回滾或提交之前不被釋放。
    posted @ 2005-06-08 19:11 小馬歌 閱讀(1476) | 評論 (0)編輯 收藏
    僅列出標題
    共95頁: First 上一頁 87 88 89 90 91 92 93 94 95 下一頁 
     
    主站蜘蛛池模板: 亚洲人成影院在线观看| 国产免费69成人精品视频| 亚洲香蕉成人AV网站在线观看| 小说专区亚洲春色校园| 四虎永久免费网站免费观看| 亚洲国产精华液2020| 日日夜夜精品免费视频| 水蜜桃视频在线观看免费| 亚洲国产成人乱码精品女人久久久不卡 | 亚洲成a人片在线观看无码| 今天免费中文字幕视频| 亚洲四虎永久在线播放| 100000免费啪啪18免进| 国产精品亚洲片夜色在线| 四虎影视永久免费观看地址| 无码毛片一区二区三区视频免费播放 | 中文字幕在线免费看线人| 亚洲国产日韩一区高清在线| 18pao国产成视频永久免费| 亚洲狠狠成人综合网| 亚洲Av无码乱码在线播放| 成人电影在线免费观看| 亚洲国产日产无码精品| 四虎免费永久在线播放| 中文字幕免费不卡二区| 亚洲中文字幕无码中文| 亚洲国产精品无码久久青草| 久久大香伊焦在人线免费| 亚洲国产av美女网站| 国产18禁黄网站免费观看| 大地资源网高清在线观看免费| 亚洲精品亚洲人成在线麻豆| 免费A级毛片无码久久版| 久久国产乱子精品免费女| 亚洲人片在线观看天堂无码| 一级毛片a免费播放王色| 黄色成人网站免费无码av| 一级黄色免费网站| 亚洲一区二区三区高清| 少妇亚洲免费精品| 免费观看激色视频网站bd|