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

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

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

    konhon

    忘掉過去,展望未來。找回自我,超越自我。
    逃避不一定躲的過, 面對不一定最難過, 孤單不一定不快樂, 得到不一定能長久, 失去不一定不再擁有, 可能因為某個理由而傷心難過, 但我卻能找個理由讓自己快樂.

    Google

    BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
      203 Posts :: 0 Stories :: 61 Comments :: 0 Trackbacks

    2007年4月4日 #

       很多股民常常感到孤獨無助,買入的股票總是被套,這里面折射出一個問題,那就是你沒有真正的掌握好買入點,今天我就在這里給大家講一講如何把握買入點。

      由于股票變化無常,主力更是絞盡腦汁和散戶斗智斗勇,所以買入法也沒有固定格式,我在這里只簡單的介紹幾種很有效的方法,僅供你借鑒。

         1、量縮法。顧名思義,就是當股票在一定“趨勢和條件”下,成交量開始萎縮到不能再萎縮時,說明下跌能量消耗已盡,此時就是最好的買入點。所謂的“趨勢和條件”是講——這只股票運行趨勢必須是在上升通道或低位震蕩中,當它連續(xù)下跌兩到三天時,成交量已經(jīng)萎縮很多,股價波動范圍已經(jīng)很小,盤中也不再見有大的買單,特別是遇到大盤下跌時,它也不再下跌,這說明這只股票到了“谷”底,隨時有反彈和新的行情發(fā)動,此時就是最價買入點。例如600297在1月30號到2月2號,連續(xù)下跌了四天,切成交量逐步萎縮,2月2號就是個最價買點。

         2、前高突破法。當一只股票經(jīng)過一段時間的上漲,之后開始進入回調(diào),當經(jīng)過一段時間的調(diào)整,再次開始放量攻擊前期高點時,此時也是買入點。但是這里最難把握的就是主力的假突破,很容易上當,這需要你自己正確判斷。比方說600983在1月23達到一個高點后,2月8號開始放量攻擊前期高點,那么2月8號就是最價買點。而600717在3月8號就是一個假突破。我特別強調(diào)一點,最好是出現(xiàn)三次沖擊前期高點的股票,把握性最大。

         3、長陽之后等待法。就是當某只股票出現(xiàn)長陽甚至是漲停時,第二天它很可能不再連續(xù)拉升,而是出現(xiàn)小幅的調(diào)整,此時也是買入點,例如600723在1月18日就是一個買入點。

         4、誘空識破法。很多主力在進入下一波的大行情中,往往做最后的誘空洗盤。此時也是最價買入法,這需要你高超的識盤技巧。例如,600176在1月31號,出現(xiàn)了一條放量的長陰,其實那是誘空,做出這樣的判斷是要對這只股票的基本面和技術(shù)面都非常熟悉才行。

         5、大換手率的等待法。當某只股票在低位(特別強調(diào)是低位)出現(xiàn)大換手率時,說明主力殺入,你隨時可以跟進。例如600178在1月19和22連續(xù)兩天出現(xiàn)超過12%的還手率,之后再出現(xiàn)低點時,你就可以殺入了。
    posted @ 2007-04-04 06:52 konhon 優(yōu)華 閱讀(1432) | 評論 (0)編輯 收藏

    2007年3月29日 #

    http://www.openitpower.com/wenzhang/97/10846_1.html

      與TTable、TQuery一樣,TClientDataSet也是從TDataSet繼承下來的,它通常用于多層體系結(jié)構(gòu)的客戶端。TClientDataSet最大的特點是它不依賴于BDE(Borland Database Engine),但它需要一個動態(tài)鏈接庫的支持,這個動態(tài)鏈接庫叫DBCLIENT.DLL。在客戶端,也不需要用TDatabase構(gòu)件,因為客戶端并不直接連接數(shù)據(jù)庫。
      由于TClientDataSet是從TDataSet繼承下來的,所以,它支持諸如編輯、搜索、瀏覽、糾錯、過濾等功能。由于TClientDataSet在內(nèi)存中建立了數(shù)據(jù)的本地副本,上述操作的執(zhí)行速度很快。也正是由于TClientDataSet并不直接連接數(shù)據(jù)庫,因此,客戶程序必須提供獲取數(shù)據(jù)的機制。在Delphi 4中,TClientDataSet有三種途徑獲取數(shù)據(jù):
    .從文件中存取數(shù)據(jù)。
    .從本地的另一個數(shù)據(jù)集中獲取數(shù)據(jù)。
    .通過IProvider接口從遠程數(shù)據(jù)庫服務器獲取數(shù)據(jù)。
      在一個客戶程序中,可以同時運用上述三種機制獲取數(shù)據(jù)。
    11.1 瀏覽和編輯數(shù)據(jù)
      和其他數(shù)據(jù)集構(gòu)件一樣,可以用標準的數(shù)據(jù)控件顯示由TClientDataSet引入的數(shù)據(jù)集,當然,這需要借助于TDataSource構(gòu)件。
      由于TClientDataSet是從TDataSet繼承下來的,所以,凡是其他數(shù)據(jù)集構(gòu)件支持的功能,TClientDataSet構(gòu)件也大致具備。不同的是,TClientDataSet能夠在內(nèi)存中建立數(shù)據(jù)的副本,因此,TClientDataSet比其他數(shù)據(jù)集構(gòu)件增加了一些特殊的功能。
    11.1.1 瀏覽數(shù)據(jù)
      可以用標準的數(shù)據(jù)控件顯示由TClientDataSet引入的數(shù)據(jù)集。在運行期,可以調(diào)用諸如First、GotoKey、Last、Next和Prior等函數(shù)來瀏覽數(shù)據(jù)。
      TClientDataSet也支持書簽功能,可以用書簽來標記某條記錄,以后就可以方便地找到這條記錄。
      對于TTable、TQuery等數(shù)據(jù)集構(gòu)件來說,只能讀RecNo屬性來判斷當前記錄的序號。對于TClientDataSet構(gòu)件來說,還可以寫RecNo屬性,使某一序號的記錄成為當前記錄。
    11.1.2 CanModify屬性
      TDataSet的CanModify屬性用于判斷數(shù)據(jù)集中的數(shù)據(jù)是否可以修改。CanModify屬性本身是只讀的,也就是說,數(shù)據(jù)是否能夠修改不取決于應用程序。
      不過,TClientDataSet構(gòu)件有其特殊性,因為TClientDataSet已經(jīng)把數(shù)據(jù)在內(nèi)存中建立了副本,因此,應用程序可以決定是否允許修改數(shù)據(jù)。如果不允許用戶修改數(shù)據(jù),只要把ReadOnly屬性設(shè)為True,此時,CanModify屬性肯定返回False。
      與其他數(shù)據(jù)集構(gòu)件不同,修改TClientDataSet構(gòu)件的ReadOnly屬性時,不需要事先把Active屬性設(shè)為True。
    11.1.3 取消修改
      TClientDataSet傳輸數(shù)據(jù)的基本單位稱為數(shù)據(jù)包,當前的數(shù)據(jù)包可以由Data屬性來訪問。不過,用戶對數(shù)據(jù)的修改并不直接反映到Data屬性中,而是臨時寫到一個日志即Delta屬性中,這樣做的好處是以后隨時可以取消修改。
      不過,這里要說明一點,盡管用戶的修改并沒有反映到Data,當用戶在數(shù)據(jù)控件中看到的卻是最新修改的數(shù)據(jù)。如果一條記錄被反復修改了多次,用戶看到的只是最新的數(shù)據(jù),但日志中卻記載了多次。
      要取消上一次的修改,調(diào)用UndoLastChange函數(shù)。UndoLastChange需要傳遞一個布爾類型的參數(shù)叫FollowChange,如果FollowChange參數(shù)設(shè)為True,光標就移到被恢復的記錄上,如果FollowChange參數(shù)設(shè)為False,光標仍然在當前記錄上。
      ChangeCount屬性返回日志中記載的修改次數(shù)。如果一條記錄被反復修改了多次,每調(diào)用一次UndoLastChange能夠逐級取消上一次的修改。
      UndoLastChange只能取消上一次的修改,如果想一下子取消所有的修改,首先要選擇一個記錄,然后調(diào)用RevertRecord。RevertRecord將從日志中取消所有對當前記錄的修改。
      TClientDataSet還有一個SavePoint屬性,它能把當前的編輯狀態(tài)保存起來,以后隨時可以返回當時的狀態(tài)。例如,可以這樣保存當前的狀態(tài):
      BeforeChanges := ClientDataSet1.SavePoint;
      以后,可以這樣來恢復當時的狀態(tài):
      ClientDataSet1.SavePoint := BeforeChanges;
      應用程序可以保存多處狀態(tài),可以恢復其中一個狀態(tài),不過,一旦某個狀態(tài)被恢復,在其之后的狀態(tài)就無效。
      如果要一下子取消日志中記載的所有修改,可以調(diào)用CancelUpdates函數(shù)。CancelUpdates將把日志清空,取消所有的修改。
      如果LogChanges屬性設(shè)為False,用戶對數(shù)據(jù)的修改就會直接反映到Data屬性中。
    11.1.4 合并修改
      要把日志中記載的修改合并到Data屬性中,有兩種方式,具體使用哪一種方式,取決于應用程序獲取數(shù)據(jù)的機制。不過,不管是哪種機制,合并后,日志自動被清空。
      對于一個從文件中獲取數(shù)據(jù)的程序來說,只要調(diào)用MergeChangeLog函數(shù),就把日志中記載的修改合并到Data屬性中。不用擔心其他用戶同時修改了數(shù)據(jù)。
      對于一個從應用服務器獲取數(shù)據(jù)的程序來說,就不能調(diào)用MergeChangeLog來合并數(shù)據(jù),而要調(diào)用ApplyUpdates函數(shù),ApplyUpdates會把日志中記載的修改傳遞給應用服務器,待應用服務器成功地把數(shù)據(jù)更新了數(shù)據(jù)庫服務器后,才會合并到Data屬性中。
    11.1.5 糾錯
      TClientDataSet支持糾錯功能。一般情況下,需要自己建立糾錯規(guī)則,以便對用戶輸入的數(shù)據(jù)進行糾錯。
      此外,如果獲得了IProvider接口的話,還可以從遠程服務器引入糾錯規(guī)則。
      有時候,客戶端可能需要暫時禁止糾錯,因為客戶端從應用服務器檢索數(shù)據(jù)是分階段進行的,在所有的數(shù)據(jù)檢索完畢之前,有些糾錯規(guī)則很可能會報錯。
    要暫時禁止糾錯,可以調(diào)用DisableConstraints,要重新允許糾錯,可以調(diào)用EnableConstraints函數(shù)。DisableConstraints和EnableConstraints實際上都是作用于一個內(nèi)部的計數(shù)。
    11.2 索 引
      使用索引有這么幾個好處:
    .在數(shù)據(jù)集中定位記錄比較快。
    .能夠在兩個數(shù)據(jù)集之間建立Lookup或Master/Detail關(guān)系。
    .可以對記錄排序。
      在多層體系結(jié)構(gòu)中,當客戶程序從應用服務器檢索數(shù)據(jù)時,它同時獲得了默認的索引。默認的索引叫DEFAULT_ORDER,可以使用這個索引排序,但不能修改或刪除這個索引。
      除了默認的索引外,TClientDataSet還對日志中記載的記錄自動建立了一個副索引叫CHANGEINDEX。與DEFAULT_ORDER一樣,不能修改或刪除這個副索引。
      另外,還可以使用數(shù)據(jù)集中已建立的其他索引,或者自己建立索引。
    11.2.1 創(chuàng)建一個新的索引
      要創(chuàng)建一個新的索引,可以調(diào)用AddIndex。AddIndex需要傳遞若干個參數(shù):
      一是Name參數(shù),用于指定索引名。在運行期切換索引時需要用到索引的名稱。
      二是Fields參數(shù),它是一個字符串,用于指定索引中的字段名,彼此之間用分號隔開。
      三是Options參數(shù),用于設(shè)置索引的選項,包含ixDescending元素表示按降序排列,包含ixCaseInsensitive元素表示大小寫不敏感。
      四是DescFields參數(shù),它也是一個字符串,用于指定若干個字段名,這些字段將按照降序排列。
      五是CaseInsFields參數(shù),它的作用與DescFields參數(shù)類似,包含在CaseInsFields參數(shù)中的字段將對大小寫不敏感。
      六是GroupingLevel參數(shù),用于指定分組級別,其值不能超過索引中的字段數(shù)。
      下面的代碼創(chuàng)建了一個索引:
    If Edit1.Text <> '' and ClientDataSet1.Fields.FindField(Edit1.Text) then
    Begin
    ClientDataSet1.AddIndex(Edit1.Text+'Index',Edit1.Text,  
      [ixCaseInsensitive],'','',0);
    ClientDataSet1.IndexName := Edit1.Text + 'Index';
    End;
    為了避免創(chuàng)建一個索引,可以臨時用IndexFieldNames屬性來指定若干個字段,讓數(shù)據(jù)集按這些字段排序。
    11.2.2 刪除和切換索引
      要刪除一個先前創(chuàng)建的索引,可以調(diào)用DeleteIndex并指定要刪除的索引名稱。注意:DEFAULT_ORDER和CHANGEINDEX不能刪除。
      如果建立了多個索引,可以任意選擇其中的一個索引,這就要用到IndexName屬性。
    11.2.3 用索引把數(shù)據(jù)分組
      選擇了一個索引后,數(shù)據(jù)集將自動按其中的字段進行排序。這樣,臨近的記錄往往在關(guān)鍵字段上含有相同的值。例如,假設(shè)有一個表是這樣的:
    SalesRep Customer OrderNo Amount
    1      1     5    100
    1      1     2    50
    1      2     3    200
    1       2     6    75
    2      1     1    10
    2      3     4    200
      可以看出,SalesRep字段的值有重復的。對于SalesRep字段的值為1的來說,Customer字段的值也有重復的。這就是說,可以按SalesRep字段分組,進而再按Customer字段分組。顯然,這里的分組級別是不同的,按SalesRep字段建立的分組屬于第一級,按Customer字段建立的分組屬于第二級。實際上,分組級別取決于字段在索引中的順序。
      TClientDataSet可以決定是否按照分組級別來顯示記錄的值。例如,也許想以下面這種形式顯示數(shù)據(jù):
    SalesRep Customer OrderNo Amount
    1      1    5    100
               2    50
           2    3    200
               6    75
    2      1    1    10
    2      3    4    200
      要判斷當前記錄某一級的什么位置,可以調(diào)用GetGroupState函數(shù)。GetGroupState函數(shù)需要傳遞一個參數(shù),用于指定分組級別。
    11.3 計 算 字 段
      與其他數(shù)據(jù)集一樣,也可以在TClientDataSet建立的數(shù)據(jù)集中增加計算字段。計算字段的值是基于同一個記錄中的其他字段計算出來的。
      在其他數(shù)據(jù)集中,只要用戶修改了數(shù)據(jù)或當前記錄發(fā)生改變,就會觸發(fā)OnCalcFields事件,換句話說,計算字段的值就被計算一次。
      TClientDataSet引入了“內(nèi)部計算字段”的概念。與一般的計算字段不同的是,內(nèi)部計算字段的值將隨其他字段的值一起存取,這樣,只有當用戶修改了數(shù)據(jù)才會觸發(fā)OnCalcFields事件,如果僅僅改變了當前記錄,不會觸發(fā)OnCalcFields事件。也就是說,內(nèi)部計算字段的值需要重新計算的機會大大減少。
      在處理OnCalcFields事件的句柄中,首先要判斷State屬性。如果State屬性返回dsInternalCalc,此時需要計算內(nèi)部計算字段的值。如果State屬性返回dsCalcFields,此時需要計算一般的計算字段的值。
    11.4 統(tǒng) 計 值
      TClientDataSet增加了統(tǒng)計的功能,它可以基于分組自動計算總和、平均、計數(shù)、最大、最小值。當用戶編輯數(shù)據(jù)時,這些統(tǒng)計值會自動跟著變化。
    11.4.1 指定統(tǒng)計方式
      要指定怎樣進行統(tǒng)計,就要用到Aggregates屬性。這個屬性是一個TAggregates對象,它用于管理一組TAggregate對象。
      在設(shè)計期,可以單擊Aggregates屬性邊上的省略號按鈕打開如圖11.1所示
    的編輯器。
      圖11.1 管理一組TAggregate對象
      單擊按鈕可以增加一個TAggregate對象,單擊按鈕可以刪減一個TAggregate對象,單擊按鈕可以把TAggregate對象前移,單擊按鈕可以把TAggregate對象后移。
      可以用字段編輯器專門創(chuàng)建一個用于表達統(tǒng)計值的字段,該字段的類型必須是“Aggregate”。Delphi 4會自動創(chuàng)建一個TAggregate對象,并加到Aggregates屬性中。選擇一個TAggregate對象,Object Inpector將顯示該對象的屬性。
      其中,Expression屬性用于指定統(tǒng)計表達式,例如:
    Sum(Field1)
      也可以是比較復雜的表達式:
    Sum(Qty * Price) - Sum(AmountPaid)
      在表達式中,可以使用下列統(tǒng)計運算符:
    .Sum計算一組數(shù)據(jù)的總和。
    .Avg計算一組數(shù)據(jù)的平均值。
    .Count計算一組數(shù)據(jù)中的非空值的個數(shù)。
    .Min計算一組數(shù)據(jù)的最小值。
    .Max計算一組數(shù)據(jù)的最大值。
      除了上述幾個統(tǒng)計運算符外,還可以使用過濾條件中所能使用的運算符,但不能嵌套。在一個表達式中,可以混合出現(xiàn)幾個統(tǒng)計值或常量,但不能混合出現(xiàn)統(tǒng)計值和字段。
      Sum(Qty * Price){合法}
      Max(Field1) - Max(Field2){合法}
      Avg(DiscountRate) * 100{合法}
      Min(Sum(Field1)){非法,不能嵌套}
      Count(Field1) - Field2{非法,統(tǒng)計值和字段不能混合出現(xiàn)在一個表達式中}
    11.4.2 指定分組
      默認情況下,統(tǒng)計值是基于數(shù)據(jù)集中所有的記錄計算出來的。不過,也可以針對一部分記錄計算統(tǒng)計值,這就需要事先建立分組。
      前面在介紹索引時已經(jīng)提到分組的概念。可以通過IndexName屬性和GroupingLevel屬性來選擇使用哪個索引以及最大的分組級別。
      例如,假設(shè)有一個表是這樣的:
    SalesRep Customer OrderNo Amount
    1      1     5    100
    1      1     2    50
    1      2     3    200
    1       2     6    75
    2      1     1    10
    2      3     4    200
      如果要按SalesRep字段分組,并且指定其中的第一級,程序代碼應當這樣寫:
    Agg.Expression := 'Sum(Amount)';
    Agg.IndexName := 'SalesCust';
    Agg.GroupingLevel := 1;
    Agg.AggregateName := 'Total for Rep';
    11.4.3 怎樣獲取統(tǒng)計值
      要獲取統(tǒng)計值,可以調(diào)用TAggregate對象的Value函數(shù)。如果統(tǒng)計值是基于數(shù)據(jù)集中所有的記錄計算出來的,隨時可以調(diào)用Value函數(shù)。如果統(tǒng)計值是基于分組計算出來的,必須保證當前記錄正好位于該分組內(nèi)。因此,在調(diào)用Value之前,最好先調(diào)用GetGroupState函數(shù)看看當前記錄是否位于該分組內(nèi)。
      要在數(shù)據(jù)控件中顯示統(tǒng)計值,必須事先在字段編輯器中創(chuàng)建一個永久字段對象,該字段的類型必須是Aggregate。
    11.5 數(shù) 據(jù) 包
      通過Data屬性可以訪問客戶程序從應用服務器檢索到的數(shù)據(jù)。程序示例如下:
    Procedure TForm1.Button1Click(Sender: TObject);
    Begin
    ClientDataSet1.Data := ClientDataSet1.Provider.DataRequest(FilterEdit.Text);
    End;
    11.5.1 直接對Data屬性賦值
      前面講過,客戶程序既可以通過IProvider接口獲取數(shù)據(jù),也可以從另一個數(shù)據(jù)集獲取數(shù)據(jù),后者就是通過Data屬性賦值的。程序示例如下:
      ClientDataSet1.Data := ClientDataSet2.Data;
      一旦Data被賦值,就可以用標準的數(shù)據(jù)控件顯示這些數(shù)據(jù)。
      注意:當從另一個數(shù)據(jù)集獲取數(shù)據(jù)時,另一個數(shù)據(jù)集的日志也將被復制過來,但不包括原來的范圍和過濾條件。
      如果要從另一個基于BDE的數(shù)據(jù)集中獲取數(shù)據(jù),可以通過數(shù)據(jù)集構(gòu)件的Provider屬性,程序示例如下:
      ClientDataSet1.Data := Table1.Provider.Data;
      如果要從一個自定義的數(shù)據(jù)集獲取數(shù)據(jù),首先要創(chuàng)建一個臨時的TProvider構(gòu)件,然后設(shè)置其DataSet屬性指定這個自定義的數(shù)據(jù)集。程序示例如下:
    TempProvider := TDataSetProvider.Create(Form1);
    TempProvider.DataSet := SourceDataSet;
    ClientDataSet1.Data := TempProvider.Data;
    TempProvider.Free;
    11.5.2 在數(shù)據(jù)包中加入自定義的信息
      可以把自定義的信息加到數(shù)據(jù)包中。當把數(shù)據(jù)保存到文件或流中時,這些自定義的信息也將保存到文件或流中。如果把數(shù)據(jù)包直接賦值給另一個數(shù)據(jù)集的話,這些自定義的信息也將被復制。
      要把自定義的信息加到數(shù)據(jù)包中,可以調(diào)用SetOptionalParam函數(shù)。要從數(shù)據(jù)包中檢索自定義的信息,可以調(diào)用GetOptionalParam。程序示例如下:
    Procedure TAppServer.Provider1UpdateData(Sender: TObject; DataSet: TClientDataSet);
    var
    WhenProvided: TDateTime;
    Begin
    WhenProvided := DataSet.GetOptionalParam('TimeProvided');
    ...
    End;
    11.5.3 克隆另一個數(shù)據(jù)集
      調(diào)用TClientDataSet的CloneCursor函數(shù)可以獲得一個數(shù)據(jù)集的完全相同的副本。它與直接通過Data屬性賦值是有區(qū)別的。
      區(qū)別之一:數(shù)據(jù)在兩個數(shù)據(jù)集之間是共享的,修改其中一個將同時修改另一個。
      區(qū)別之二:除了數(shù)據(jù)外,CloneCursor函數(shù)還復制了一些屬性和事件,這取決于Reset和KeepSettings參數(shù)怎樣設(shè)置。
       CloneCursor函數(shù)需要傳遞三個參數(shù),其中,Source參數(shù)指定源數(shù)據(jù)集,Reset參數(shù)和KeepSettings參數(shù)用于設(shè)置除了數(shù)據(jù)外是否還要復制下列屬性和事件:Filter、Filtered、FilterOptions、OnFilterRecord、IndexName、MasterSource、MasterFields、ReadOnly、RemoteServer、ProviderName、Provider。
      如果Reset和KeepSettings參數(shù)都設(shè)為False,源數(shù)據(jù)集的上述屬性和事件都將被復制給目標數(shù)據(jù)集。如果Reset參數(shù)設(shè)為True,目標數(shù)據(jù)集的上述屬性和事件都將被清空。如果Reset參數(shù)設(shè)為False,而KeepSettings參數(shù)設(shè)為True,目標數(shù)據(jù)集的上述屬性和事件不變,不過,必須保證這些屬性和事件與克隆后的數(shù)據(jù)相容。
    11.6 與應用服務器通訊
      在多層體系結(jié)構(gòu)中,客戶程序通過IProvider接口與應用服務器交換數(shù)據(jù)。這一章介紹怎樣在客戶端獲得IProvider接口、怎樣向應用服務器傳遞參數(shù)、怎樣向應用服務器請求數(shù)據(jù)、怎樣把用戶對數(shù)據(jù)的修改寫到數(shù)據(jù)庫中。
    11.6.1 怎樣在客戶端獲得IProvider接口
      在單層應用程序以及工作在“公文包”模式下的多層應用程序中,不需要用到IProvider接口。而在多層體系結(jié)構(gòu)中,客戶程序要與應用服務器交換數(shù)據(jù),首先必須獲得IProvider接口,這就要用到RemoteServer屬性和ProviderName屬性。
      RemoteServer屬性用于指定客戶端的MIDAS連接構(gòu)件。MIDAS連接構(gòu)件又稱Data Broker,用于建立和維護與應用服務器的連接。
      在設(shè)計期,正確設(shè)置了RemoteServer屬性后,就可以在對象觀察器中為ProviderName屬性選擇一個值,實際上就是選擇應用服務器上的一個TProvider構(gòu)件。
    11.6.2 向應用服務器傳遞參數(shù)
      客戶程序可以向應用服務器傳遞參數(shù),這些參數(shù)實際上是傳遞給應用服務器上的TQuery構(gòu)件或TStoredProc構(gòu)件。既可以在設(shè)計期也可以在運行期設(shè)置參數(shù)。
      在設(shè)計期,可以單擊Params屬性邊上的省略號按鈕,打開一個如圖11.2所示的編輯器。
      圖11.2 設(shè)置參數(shù)
      單擊按鈕可以增加一個參數(shù),單擊按鈕可以刪減一個參數(shù),單擊按鈕可以把一個參數(shù)前移,單擊按鈕可以把一個參數(shù)后移。
      選擇一個參數(shù),對象觀察器將顯示該參數(shù)(TParam對象)的屬性。
      在運行期可以調(diào)用TParams的CreateParam函數(shù)來創(chuàng)建一個參數(shù)。例如,下面的代碼創(chuàng)建了一個參數(shù)叫CustNo,它的使用類型是ptInput,數(shù)據(jù)類型是ftInteger,它的值設(shè)為605。
    With ClientDataSet1.Params.CreateParam(ftInteger, 'CustNo', ptInput) Do
    AsInteger := 605;
      設(shè)置好參數(shù)以后,如果TClientDataset的Active屬性是False,只要把Active屬性設(shè)為True,這些參數(shù)將被自動傳遞給應用服務器。如果Active屬性已經(jīng)為True,就要調(diào)用SendParams函數(shù)把參數(shù)傳遞給應用服務器。
      注意:傳遞給應用服務器的參數(shù)必須與TQuery構(gòu)件或TStoredProc構(gòu)件的參數(shù)匹配,包括名稱、數(shù)據(jù)類型和參數(shù)類型。
    11.6.3 怎樣向應用服務器請求數(shù)據(jù)
      TClientDataSet提供了兩個屬性和三個方法,用于怎樣向應用服務器請求數(shù)據(jù):
      一是FetchOnDemand屬性。如果這個屬性設(shè)為True,TClientDataSet會根據(jù)需要自動檢索附加的數(shù)據(jù)包,例如BLOB字段的值或者嵌套表的內(nèi)容。如果這個屬性設(shè)為False,程序需要顯式地調(diào)用GetNextPacket才能獲得這些附加的數(shù)據(jù)包。
      二是PacketRecords屬性,用于設(shè)置一個數(shù)據(jù)包中最多可容納的記錄數(shù),設(shè)為-1表示一個數(shù)據(jù)包可以容納數(shù)據(jù)集的所有記錄。
      三是GetNextPacket函數(shù),用于向應用服務器檢索下一個數(shù)據(jù)包,并把檢索到的數(shù)據(jù)包添加到前一次檢索到的數(shù)據(jù)包的后面。這個函數(shù)返回實際檢索到的記錄數(shù)。
      四是FetchBlobs過程,用于從應用服務器檢索BLOB字段的值。如果FetchOnDemand屬性設(shè)為True,就沒必要調(diào)用FetchBlobs函數(shù)。
      五是FetchDetails過程,用于檢索嵌套表中的數(shù)據(jù)。如果FetchOnDemand屬性設(shè)為True,就沒必要調(diào)用FetchDetails函數(shù)。
    11.6.4 更新數(shù)據(jù)庫
      在多層體系結(jié)構(gòu)中,用戶在客戶端修改了數(shù)據(jù)后,需要把最新的數(shù)據(jù)寫到數(shù)據(jù)庫中,這就要調(diào)用TClientDataSet的ApplyUpdates函數(shù)。
      ApplyUpdates只需要傳遞一個參數(shù)叫MaxErrors,用于指定一個整數(shù),當遇到無法更新的記錄超過這個數(shù)時,此次更新就中止。如果MaxErrors參數(shù)設(shè)為0,表示只要遇到一個錯誤更新就中止,客戶端的日志保持不變。如果MaxErrors參數(shù)設(shè)為-1,當應用服務器發(fā)現(xiàn)有錯誤的記錄,就嘗試更新下一個記錄,等所有的記錄都嘗試過以后才返回。
      ApplyUpdates會自動調(diào)用Reconcile函數(shù),進而調(diào)用應用服務器上的TProvider構(gòu)件的ApplyUpdates函數(shù)去更新遠程的數(shù)據(jù)庫服務器。沒有被DBMS服務器認可的記錄通過Reconcile返回給客戶端,此時將在客戶端觸發(fā)OnReconcileError事件讓您更正錯誤。最后,ApplyUpdates函數(shù)返回仍然沒有被認可的記錄數(shù)。
    11.7 在文件中存取數(shù)據(jù)
      要從文件中讀取數(shù)據(jù),可以調(diào)用LoadFromFile函數(shù)。LoadFromFile函數(shù)需要傳遞一個參數(shù),用于指定文件名。文件名應包含完整的路徑。如果客戶程序總是從一個固定的文件中讀取數(shù)據(jù),可以設(shè)置FileName屬性指定一個文件名,以后,當TClientDataSet引入的數(shù)據(jù)集打開時,就自動從這個文件中讀取數(shù)據(jù),不需要調(diào)用LoadFromFile。
      要從流中讀取數(shù)據(jù),可以調(diào)用LoadFromStream。LoadFromStream需要傳遞一個參數(shù),用于指定一個流對象。
      注意:LoadFromFile(LoadFromStream)只能從先前用SaveToFile(SaveToStream)保存的文件中讀取數(shù)據(jù)。
      要把數(shù)據(jù)保存到文件中,可以調(diào)用SaveToFile函數(shù)。SaveToFile需要傳遞一個參數(shù),用于指定文件名。如果指定的文件已存在,文件中的數(shù)據(jù)將被覆蓋。如果客戶程序總是把數(shù)據(jù)保存到一個固定的文件中,可以設(shè)置FileName屬性指定一個文件名,當TClientDataSet引入的數(shù)據(jù)集關(guān)閉時,就自動把數(shù)據(jù)保存到這個文件中,不需要調(diào)用SaveToFile。
      要把數(shù)據(jù)保存到流中,可以調(diào)用SaveToStream。SaveToStream需要傳遞一個參數(shù),指定一個流對象。
      注意:當把數(shù)據(jù)保存到文件或流中時,日志中記載的修改仍然保留。這樣,當下次調(diào)用LoadFromFile或LoadFromStream讀取數(shù)據(jù)時,仍然可以恢復原來的數(shù)據(jù)。
    posted @ 2007-03-29 05:57 konhon 優(yōu)華 閱讀(1641) | 評論 (0)編輯 收藏

    2007年3月28日 #

    ? 近日(呵呵,這篇文章是去年寫的)用了兩個月開發(fā)了一個物流信息系統(tǒng),這個系統(tǒng)是兩層、三層相結(jié)合,C/SB/S相結(jié)合的系統(tǒng)。雖然限于時間的緊張和人手的原因,系統(tǒng)規(guī)模不是很大,但是其中涉及的技術(shù)卻很全面。在這個《開發(fā)技術(shù)篇》中我們將講解我在開發(fā)系統(tǒng)中遇到的技術(shù)問題及解決方案,希望對大家有幫助。對于物流信息系統(tǒng)的分析設(shè)計問題,我將在另一篇文章《物流信息系統(tǒng)開發(fā)手記――系統(tǒng)構(gòu)架篇》中講解。

    ?

    一、Midas的安全問題。

    ??? Midas技術(shù)是Delphi中進行三層開發(fā)的首選技術(shù),它不僅有純DCOM/COM+(COM+技術(shù)是.NET技術(shù)的基礎(chǔ))的優(yōu)點,而且也結(jié)合了Delphi的快速開發(fā)特性,可以快速開發(fā)出想要的系統(tǒng),其開發(fā)速度是用VC,PB等開發(fā)DCOM的數(shù)十倍,把程序員從煩雜的代碼中解脫出來,從而將更多的精力投入到業(yè)務邏輯的設(shè)計中去。

    ??? 但是Midas技術(shù)的一個最令人擔憂的就是它的安全問題:

    遠端只要知道應用服務器的端口號即可訪問到應用服務器,而一旦訪問到應用服務器,TClientDataSet即可獲得ProviderNames列表。一旦知道了ProviderNames列表,這就相當于將數(shù)據(jù)庫暴露在外了。

    關(guān)于可輕易獲得ProviderNames列表的問題,我使用下面的方法解決:

    ?在服務器端定義一個

    LoginMTS(const AUserId, APassword: WideString): WordBool;

    方法。初始狀態(tài)下,所有的DataSetProvider和數(shù)據(jù)集的連接斷開。用戶必須調(diào)用LoginMTS并傳遞用戶名和密碼,登陸成功才將DataSetProvider和數(shù)據(jù)集的連接打開。這樣如果用戶驗證沒有通過,即使它獲得了ProviderNames列表也沒法調(diào)用接口中的方法對數(shù)據(jù)庫進行操作。

    二、Midas中主從表的實現(xiàn)

    主從表的應用在信息系統(tǒng)中應用很廣。在兩層開發(fā)中我們可以通過直接建立兩個數(shù)據(jù)集之間為主從關(guān)系來實現(xiàn)主從表;在三層中雖然我們?nèi)匀豢梢酝ㄟ^直接建立兩個數(shù)據(jù)集之間為主從關(guān)系來實現(xiàn)主從表,但是這樣就要求把數(shù)據(jù)庫中所有相關(guān)的數(shù)據(jù)行都下載到本地,喪失了三層開發(fā)的優(yōu)勢。我在實際中使用下面的方法實現(xiàn)。這里我以實現(xiàn)入庫單查詢、添加、修改、刪除(CRUD)為例來講解:

    1)新建一個MTS Data Module,命名為TmtsStockInListBiz,增加如下方法:

    ??? function QueryStockInListMasterById(const AId: WideString;

    ????? var ADatas: OleVariant): WordBool; safecall;

    ??? function QueryStockInListSlaveByMasterId(const AId: WideString;

    ????? var ADatas: OleVariant): WordBool; safecall;

    ??? procedure UpdataStockInListMaster(var ADatas: OleVariant); safecall;

    ??? procedure UpdataStockInListSlave(var ADatas: OleVariant); safecall;

    ??? function GenerateStockInListId: WideString; safecall;

    ?

    QueryStockInListMasterById作用是根據(jù)入庫單單號查詢?nèi)霂靻蔚幕拘畔ⅲㄈ霂烊掌凇⒇撠熑说龋?/span>Aid為入庫單單號,Adatas為返回值,其格式就是Midas的數(shù)據(jù)包,可以將其附給ClientDatSetData屬性。

    QueryStockInListSlaveByMasterId作用是根據(jù)入庫單單號查詢?nèi)霂靻蔚脑敿毿畔ⅲㄉ唐窏l碼,數(shù)量)

    UpdataStockInListMaster是對入庫單主表進行刪除、添加、修改操作。只要將ClientDataSetDelta屬性做為傳遞即可。

    UpdataStockInListSlave是對入庫單從表進行刪除、添加、修改操作。

    GenerateStockInListId是產(chǎn)生一個唯一的入庫單號。

    下面是幾個方法的代碼,都很簡單,就不多解釋了,可以查看Delphi的幫助。

    function TmtsStockInListBiz.QueryStockInListMasterById(

    ? const AId: WideString; var ADatas: OleVariant): WordBool;

    begin

    ? result := false;

    ? ADatas := null;

    ? try

    ??? cdsQuery.Close;

    ??? cdsQuery.CommandText := 'select * from t_StockInListMaster where Id=:Id';

    ??? cdsQuery.Params.ParamByName('Id').AsString := AId;

    ??? cdsQuery.Open;

    ??? if cdsQuery.RecordCount > 0 then

    ??? begin

    ????? result := true;

    ????? ADatas := cdsQuery.Data;

    ??? end;

    ? finally

    ??? cdsQuery.Close;

    ? end;

    end;

    ?

    procedure TmtsStockInListBiz.UpdataStockInListMaster(

    ? var ADatas: OleVariant);

    var

    ? eCount: Integer;

    ? OwnerData: OleVariant;

    begin

    ? DCOMConStockInList.GetServer.AS_ApplyUpdates('dspStockInListMaster',

    ??? ADatas, -1, eCount, OwnerData);

    end;

    ?

    function TmtsStockInListBiz.GenerateStockInListId: WideString;

    var

    ? LPrior: string;

    ? i: Integer;

    begin

    ? cdsQuery.Close;

    ? cdsQuery.CommandText := 'select top 1 id from t_StockInListMaster order by id desc';

    ? cdsQuery.Open;

    ? LPrior := cdsQuery.FieldByName('Id').AsString;

    ? i := StrToIntDef(RightStr(LPrior,8),0);

    ? Inc(i);

    ? result := 'RK' + FormatFloat('00000000',i);

    ? cdsQuery.Close;

    end;

    ?

    2)、新建一個應用程序,通過DCOMConnectionSocketConnection等連接到MTS組件,然后就可以調(diào)用MTS的相應的方法實現(xiàn)客戶端功能了。

    放入cdsStockInListMaster、cdsStockInListSlave兩個ClientDataSet控件,在控件上點擊右鍵,選擇“FieldsEditor”新建于服務器中的字段同樣的字段,然后再次在控件上單擊右鍵,選擇“CreateDataSet”,建立一個本地數(shù)據(jù)庫。

    3

    根據(jù)入庫單號查詢?nèi)霂靻蔚姆椒▽崿F(xiàn):

    procedure TFormStockInList.BtnFindClick(Sender: TObject);

    var

    ? v,vs: OleVariant;

    begin

    ? if SocketConStockInList.AppServer.QueryStockInListMasterById(Trim(LEdtId.Text), v) then

    ? begin

    ??? cdsStockInListMaster.Data := v;//顯示入庫單主表(主要信息)

    ?

    ??? if SocketConStockInList.AppServer.QueryStockInListSlaveByMasterId(Trim(LEdtId.Text), vs) then

    ????? cdsStockInListSlave.Data := vs; ;//顯示入庫單從表(明細信息)

    ? end

    ? else

    ??? ShowMessage('此單不存在!');

    end;

    4)新建入庫單的實現(xiàn)

    procedure TFormStockInList.BtnNewClick(Sender: TObject);

    var

    ? LId: string;

    begin

    ? ClearCDSRecord;

    ? cdsStockInListMaster.Open;

    ? cdsStockInListMaster.Insert;

    ? LId := SocketConStockInList.AppServer.GenerateStockInListId;

    ? LEdtId.Text := LId;

    ? cdsStockInListMaster.FieldByName('Id').AsString := LId;

    ? cdsStockInListMaster.FieldByName('GenerateDate').AsDateTime := Now();

    end;

    5)提交功能的實現(xiàn)

    procedure TFormStockInList.BtnPostClick(Sender: TObject);

    var

    ? LQuerymts: ImtsQueryObjDisp;

    ? LBar: string;

    begin

    ? SetSocketConnectionConnect(SocketConQuery);

    ? LQuerymts := ImtsQueryObjDisp(SocketConQuery.GetServer);

    ?

    ? SocketConQuery.Close;

    ?

    ? if cdsStockInListMaster.RecordCount > 0 then

    ??? SocketConStockInList.AppServer.UpdataStockInListMaster(cdsStockInListMaster.Delta);

    ? if cdsStockInListSlave.RecordCount > 0 then

    ? SocketConStockInList.AppServer.UpdataStockInListSlave(cdsStockInListSlave.Delta);

    end;

    注:本文中ClientDataSet控件的名稱開頭一般為cds、TsocketConnection控件的名稱開頭一般為SocketCon。

    三、動態(tài)設(shè)置TsimpleObjectBroker的服務器列表

    procedure SetSocketConnectionConnect(AValue: TSocketConnection);

    ? procedure FillAppServerList(ABroker: TSimpleObjectBroker);

    ? var

    ??? sl: TStringList;

    ??? i, n: Integer;

    ? begin

    ??? sl := TStringList.Create;

    ??? 從配置文件中讀取服務器列表,并保存到sl;

    ??? n := sl.Count - 1;

    ??? ABroker.ServerData := null;

    ??? for i := 0 to n do

    ??? begin

    ????? ABroker.Servers.Add;

    ????? ABroker.Servers[i].ComputerName := sl.Strings[i]

    ?? ?end;

    ??? sl.Free;

    ? end;

    var

    ? LBroker: TSimpleObjectBroker;

    begin

    ? LBroker := TSimpleObjectBroker.Create(nil);

    ??? FillAppServerList(LBroker);

    ??? AValue.ObjectBroker := LBroker;

    ??? try

    ????? AValue.Connected := true;

    ??? except

    ????? raise Exception.Create('應用服務器連接錯誤!');

    ??? end;

    ??? LBroker.Free;

    end;

    posted @ 2007-03-28 05:07 konhon 優(yōu)華 閱讀(2571) | 評論 (0)編輯 收藏


      因為需要處理大量的音、視頻數(shù)據(jù),所以一套強有力的計算機系統(tǒng)及外圍硬件配置是必要的。另外,由于我們要直接輸出的是高質(zhì)量的MPG文件(而非體積龐大的AVI文件),因此,強烈建議使用視頻壓縮卡進行硬件高速壓縮,本文以較常見的MPEGator 3.1壓縮卡為例,介紹通過Premiere利用壓縮卡直接輸出MPG的辦法:

      1、制作VCD電子相冊應使用怎樣的系統(tǒng)配置?

      答:推薦的系統(tǒng)配置如下---

      CPU: PIII 500E以上

      內(nèi)存: 256M SDRAM或更大

      硬盤: 20G高速

      壓縮卡:MPEGator 3.1 刻錄機:所有能被Video Pack 4.0所支持的型號

      操作系統(tǒng):Windows 95 OSR2或Windows 98 制作軟件:Adobe Premiere 5.0/4.2、Video Pack 4.0

      輔助軟件:Paint shop Pro 6.0、ACDsee3.0、Audio Grabber 1.61 以上推薦的系統(tǒng)配置中,我們主要是采用了著名的視頻編輯軟件Adobe Premiere 5.0與性能價格比較高的MPEGator 3.0壓縮卡配合制作VCD相冊。為什么要采用這樣的配合呢?還是先讓我們來了解一下它們各自的特性吧:

      2、為什么推薦使用Premiere 5.0數(shù)字影視編輯軟件?

      答:Adobe Premiere 5.0是圖形圖像軟件巨人---Adobe公司繼廣受稱贊的Premiere 4.2后,推出的新一代桌面數(shù)字影視編輯系統(tǒng)。它具有比Premiere 4.2更為強大的圖像編輯能力,通過把動畫、位圖、數(shù)字音頻文件按照需要進行剪輯、組合,讓你可以設(shè)計出近乎隨心所欲的影視特效;在專為編輯影像片段而設(shè)計的Timeline里,利用鼠標就可完成所有的編輯操作;它的即時播放功能還使我們在發(fā)生編輯錯誤時,能夠輕松地進行修改,以節(jié)省時間與精力。更重要的是,Premiere 5.0可以提供高品質(zhì)影像輸出質(zhì)量!這一點著實令人心動。此外,它還支持制作輸出有聲有色的VCD電子相冊呢。

      3、為什么推薦使用MPEGator壓縮卡?

      答:壓縮卡方面,韓國DARIM公司生產(chǎn)的MPEGator壓縮卡(圖02)可謂是具有較高性能價格比的視頻壓縮卡:不僅帶有S-video、復合、及立體聲音頻輸入接口,可以通過攝像機、錄像機、電視及激光唱機等信號源將視頻信號實時壓縮成全I.P.B幀的標準MPEG-1格式;還支持實時預覽。最為重要的是MPEGator卡可以使流行的視頻編輯軟件通過硬件加速轉(zhuǎn)換成為MPEG-1格式?! PEGator可與Windows的其它應用程序配合產(chǎn) PEG文件,3D Studio, Adobe Premiere等各種兼容Video for Window的流行的編輯軟件都可以在生成動畫或AVI之前,直接選用其壓縮驅(qū)動程序,通過硬件加速壓縮生成為MPEG文件,有效地避免了因AVI—→MPG而導致的畫質(zhì)下降這一難題。另外,MPEGator還具有PAL/NTSC制式兼容,PCI32位總線等特點。通過以上介紹,可以看出:利用這樣的軟硬件組合,我們將能夠制作出效果比較令人滿意的多媒體VCD相冊。下面,就讓我們開始實戰(zhàn)VCD相冊的制作吧。

      4.制作VCD相冊之前,為什么要擬定提綱?

      答:制作VCD相冊之前,首先應對所制作的作品的各個方面做到心中有數(shù)。最好列個制作提綱,列出主題及各相對獨立片段的次序,以及每個片段內(nèi)的照片、音樂、旁白;將每張照片分別編上序號,并將其序號與欲添加的說明文字對應起來。這樣,在實際制作的時候就條理清晰、步驟分明,不易出現(xiàn)錯漏等現(xiàn)象。

      5.怎樣進行照片的掃描?

      答:選取一張淺色紋理紙,將其裁剪成寬155mm、高127mm(即352:288)大小的矩形模板。用雙面膠將照片粘于其上(注意居中,并使底邊高度略大于頂邊),放入掃描儀進行掃描,并以位圖(.bmp)形式存盤。此舉好處之一是使掃出的照片具有一個漂亮的彩色相框;另一個好處是可以將添加的說明文字放在相框上,而不是照片內(nèi),不會破壞照片的美感(圖07)。?


      6. 如何為照片添加說明文字?

      進入Paint Shop Pro 5.0,選擇File——open打開一幅已掃好的照片,點擊左側(cè)工具欄中的“A”鍵,接著將鼠標移至照片內(nèi)并單擊左鍵,在彈出的“Add Text”文字輸入框中輸入想要的文字,再選定字體、字號及顏色,確定文字位置后點擊“OK”,并將編輯后的照片以原文件名存盤。

     7.如何截取音軌?

      答:啟動音軌截取軟件AudioGrabber,將音樂CD放入光驅(qū),勾選想要截取的CD音軌。

      點擊控制欄中的“Settings”按鍵后勾選其中的“ASPI”項,其它選項用默認值即可。然后,進入“Norm”選項,選擇“Use normalizing”后點擊“OK”退出?,F(xiàn)在,先用鼠標點擊一下工具欄里那標有伸開手掌的“截取”(Grab)鈕,就可以開始抓取指定的音軌了。如果截獲的.WAV文件不能被正常讀取或者.WAV文件中有令人討厭的“爆音”(pops,這是令許多朋友頭痛的問題)。請在“開始—設(shè)置—控制面板—系統(tǒng)—設(shè)備管理—CDROM—屬性—設(shè)置—選項”中將“同步數(shù)據(jù)傳送”選中,然后按“確定”退出。再重新去試截取剛才有問題的音軌,您可能會發(fā)現(xiàn),問題已經(jīng)迎刃而解了。其次,若覺得光驅(qū)讀取音樂數(shù)據(jù)的速度很緩慢,請先檢查光驅(qū)上數(shù)據(jù)線是否直接接到了主板的IDE接口上。

      為了方便管理和使用,可新建Photo、Audio、Wav三個子目錄,分別用于存放照片、音樂及旁白。

      準備工作完成后,就可以開始著手制作了。為了工作得更有條理,我們一般先對每一個相對獨立的片段進行編輯制作,最后再把它們連成整體。

      8.如何設(shè)置才能讓Premier5.0利用MPEGator來進行高效硬件壓縮?

      答:首先啟動Premiere5.0。在彈出的New Project setting窗口,選擇General settings,在“編輯模式”里選“Video for window”,其下的兩個選項均選“25”(因為我們要制作的是PAL制式的VCD);然后進Video settings,在“壓縮器(Compressor)”這一項中選“DVMPEG Video (hardware)”(圖08),即選用硬件壓縮;分辨率設(shè)為352*288,幀率設(shè)為25;在Audio settings里,關(guān)鍵是在“Type(類型)”中選擇“DVMPEG Audio”---指定用硬件進行音頻壓縮;采樣頻率設(shè)為44.1KHZ,格式設(shè)為16bit--Stereo。


      9.Premiere 5.0的主界面的結(jié)構(gòu)如何?

      答:進入Premiere 5.0的主界面,我們會發(fā)現(xiàn)設(shè)計新穎的時間軸窗口(Timeline)已取代了其4.2版本中的Constraction窗口。作為Premiere 5.0的核心,Timeline的用戶窗口分為兩個部份:視頻部分和音頻部分;其中視頻部份又分為兩個主視頻剪輯軌道——Video 2和Video 1。其中,標成黑體字的Video 1部份又內(nèi)含兩個視頻剪輯軌道:Video 1A和Video 1B,它們之間的Transition軌道是視頻切換效果軌道。Premiere 5.0提供了非常豐富的視頻切換效果,包括滑動、擦除、融合、剝落、分割、爆破、漸變、突變、三維旋轉(zhuǎn)、翻頁、推動等多種劃變效果,令人目不暇接。音頻軌道Audio 1、2、3則用于放置背景音樂、配音、旁白等聲音信號?! ?

      10.如何導入圖片及配音文件?

      答:點擊“File--Import--Folder”,把剛才準備好的圖片文件及背景音樂文件輸入進來,在Project窗口下雙擊剛才輸入的文件夾,可以看到文件夾中的各文件的具體信息,雙擊該文件則可對其進行預覽。  

      11.如何設(shè)置照片的參數(shù)?

      答:將第一幅照片拖到視頻剪輯軌道Video 1A中,對其點擊鼠標右鍵,在彈出的菜單中的Duration項里設(shè)定照片的播放時間;并在菜單中的Video項里將Maintain Aspect Retio選中(圖09)——請注意,這是非常重要的一步,此項設(shè)置將使最后輸出的照片保持原本的長寬比例,而不致于使照片上的人像、景物發(fā)生變形。按上述方法將照片依次拖入Video1的A、B欄,(注意每幅照片的尾與下一幅照片首應留有重疊部份,重疊部份的時間長短依實際需要而定。把背景音樂、旁白拖入Audio欄)。如果是旁白,應特別注意旁白的時間長度應與相應照片的播放時間相當。然后,用鼠標把Timeline窗戶上方的淺藍色橫杠拉至最后一張照片的末端,以設(shè)定Premiere將進行處理的視頻片段的長度。


      12. 如何設(shè)定視頻切換特效?

      答:Premiere 5.0用戶界面上,有一個Transition/Command命令窗口,其中共有75種切換特效可供選擇。而且,其中大多數(shù)切換特效都可按自己的需要進行設(shè)置。將選中的特效用鼠標拖到Video 1窗口的Transition中兩幅照片相重疊的部分,其長度應為兩幅照片相重疊的長度。如果能根據(jù)每幅照片的特點恰當?shù)剡x擇Transitions,將使您的VCD相冊在播放時贏得更多的贊嘆之聲?! ?

      13. 如何處理背景音樂?

      答:為VCD相冊添加優(yōu)美的背景音樂,也將使你的VCD相冊平添許多迷人的魅力。然而,因為背景音樂是我們采用抓音軌的方式獲得的,這樣就不可避免地在VCD相冊一開始播放時就出現(xiàn)突兀而至的音樂聲。此外,由于音軌的長度與照片播放時間的長度往往難以很好的吻合。這樣,就可能出現(xiàn)一段VCD相冊的播放馬上就要結(jié)束,而音樂聲卻正處于高潮……。理想的狀況應該是:照片播放時,背景音樂逐漸輕柔地響起;照片播放即將結(jié)束時,音樂聲又漸漸隨之淡去。換句話說,也就是要實現(xiàn)背景音樂的淡入淡出。在Premiere 5.0中,按前述方法裝入照片及背景音樂后,單擊第一音頻軌道(Audio 1)上的那個指向右的小三角,這時會彈出該音軌的波形顯示框。可以看到該框中部有一條左右各有一方形端點的紅線——這就是控制音樂淡入淡出的關(guān)鍵。將鼠標移至紅線上,鼠標指針將變?yōu)槭中?圖10)。此時,按住鼠標左鍵即可通過增加和拖動點子來隨意確定該紅線條形狀。從起始位置開始,將線條置于從左至右漸高狀態(tài)時,即可實現(xiàn)背景音樂的淡入效果。用類似的方法還可制造音樂的淡出效果,在此不再贅述。有興趣的朋友盡可自行嘗試。?

      14. 如何設(shè)置輸出參數(shù)?

      答:輸出參數(shù)包含General、Audio、Video三項,只有正確的設(shè)備了輸出參數(shù),VCD相冊才能在VCD機上順利播放。首先選Project--Setting進入General設(shè)置:在“Editing Mode”里選“Video for window”,“Time display”及“Timebase”均選“25”;再進入Video設(shè)置,“Compressor”選“DVMPEG Video(Hardware)”,尺寸設(shè)為352*288,幀率設(shè)為25;最后設(shè)置Audio參數(shù):采樣頻率設(shè)為44.1KHZ,格式設(shè)為16bit--Stereo(圖11);Type設(shè)成“DVMPEG Audio”。在這里,音頻及視頻均設(shè)置為硬件(MPEGator卡)加速壓縮。?


      15. 如何直接輸出MPG文件?

      答:上述參數(shù)設(shè)置完畢后,接著選File-Export-movie,將剛才組合好的照片,音樂,旁白等素材,通過MPEGator卡的硬件加速直接生成高質(zhì)量的MPG文件。我們知道,如果利用Xing MPEG Encoder等進行純軟件壓縮,即使你的系統(tǒng)配置較高,其壓縮時間也將漫長得驚人:約為真實播放時間的10-20倍;而利用MPEGator卡進行硬件壓縮的話,可就太節(jié)省時間了:壓縮時間僅為真實播放時間的3倍左右,大大提高了制作效率。需要注意的是,為了便于分類,應把同一主題的內(nèi)容輸出生成一個獨立的MPG文件。

      16. 如何把電子相冊刻成VCD碟?

      前面所有辛苦的勞動,都將通過刻制成VCD碟片而變成勞動的果實。說到2.0 VCD刻錄,CeQuadrat出品的Video Pack 4.0因其較細致而周到的功能設(shè)計,是一個在業(yè)余條件下不錯的選擇,其缺點是操作相對比較繁瑣。啟動Video Pack 4.0,將剛才壓縮好的各個MPG文件依次用鼠標拖至位于主界面下方的工作框內(nèi),右鍵單擊MPG文件,在彈出的菜單選中Properties,在Playlist node中的第二個選項(即每一片段的等待時間)里把等待時間設(shè)為0秒,按“確定”退出。每個MPG文件都必須重復上述步驟,這樣可以使各獨立主題內(nèi)容切換時不至于出現(xiàn)停頓等待狀態(tài)。這時你也許發(fā)現(xiàn)了,剛才拖入工作框的各MPG文件方形圖標上下均有一個三角形缺口。原來,在Video Pack 4.0中是用連線的方式來表示各種播放次序的,而這種三角形缺口,就是這些連線的出入口。將鼠標指針移至MPG文件圖標下方的缺口,圖標里會出現(xiàn)黃顏色的“Next”字樣,此時即可開始進行連線,方法是使各MPG文件按順序首尾相連(圖12)。上述步驟完成后,點擊工具欄中的紅色的“Make CD”鈕即可開始刻錄VCD光碟了。

      17. 把電子相冊刻成VCD碟的過程中要注意哪些事項?

      要是現(xiàn)在問你:自己刻制一張VCD相冊光盤困難嗎?你肯定會說:一點都不難!

      那么,是不是就像在硬盤上拷貝文件那么輕而易舉呢?決非如此簡單。VCD相冊刻錄前進行些必要的準備工作,將能大大提高我們的刻錄成功率:  

      a.刻錄前為什么要整理硬盤?

      答:我們通常都是以硬盤作為信息源盤來進行刻錄的。由于未經(jīng)整理的磁盤文件大多呈零散狀態(tài)分布。這樣,硬盤在讀取數(shù)據(jù)時,讀寫頭就只能在零散的文件之間來回奔忙,極有可能造成不必要的延誤而導致刻出廢盤。所以,每次刻錄前對硬盤的每一個邏輯分區(qū)進行磁盤掃描和碎片整理。進行硬盤整理是成功刻錄的第一步。  

      b.為什么刻錄過程中要避免執(zhí)行任何無關(guān)程序?

      答:這些程序不僅包括屏幕保護程序和內(nèi)存駐留程序(比如某些殺毒程序),這些程序都有可能在數(shù)據(jù)流從硬盤轉(zhuǎn)移到刻錄機中光盤上的緊要關(guān)頭,來與刻錄軟件爭奪有限的系統(tǒng)資源,從而影響數(shù)據(jù)流的正常傳輸而引發(fā)緩存器欠載等問題,導致刻盤失敗。

      c.為什么使用質(zhì)量可靠的CD-R盤片?

      答:CD-R空白盤片按反射層材料的不同可分綠盤、金盤、藍盤三大類。這三種盤片并沒有明顯的優(yōu)劣差別。從特性上來說,綠盤具有較好的兼容性,另外價格很便宜;藍盤在寫入和讀取數(shù)據(jù)時有較高的準確性;金盤有較好的抗光性。關(guān)鍵的是,分別試刻不同類別和品牌的盤片,從中找出最適合你的刻錄機的那幾種?! ?

      至此,兩種不同類型的電子相冊的制作方法就介紹完畢,預祝你早日制作出自己的精美電子相冊!

    posted @ 2007-03-27 19:11 konhon 優(yōu)華 閱讀(1590) | 評論 (0)編輯 收藏

    2007年3月8日 #

    首先,我們新建一個類,存放天氣信息

    /*
    ?*?Created?on?2005-3-8
    ?*
    ?*?To?change?the?template?for?this?generated?file?go?to
    ?*?Window&gt;Preferences&gt;Java&gt;Code?Generation&gt;Code?and?Comments
    ?
    */
    package ?org.exoplatform.portlets.chinaweather.component;

    /**
    ?*?
    @author ?Administrator
    ?*
    ?*?To?change?the?template?for?this?generated?type?comment?go?to
    ?*?Window&gt;Preferences&gt;Java&gt;Code?Generation&gt;Code?and?Comments
    ?
    */
    public ? class ?Weather?{
    ?
    private ?String?city;
    ?
    private ?String?state;
    ?
    private ?String?temperature;
    ?
    private ?String?time;
    ?
    private ?String?wind;
    ?
    private ?String?windpower;
    ?
    private ? long ?UpdateTime;

    ?
    /**
    ??*?
    @return
    ??
    */
    ?
    public ?String?getTemperature()?{
    ??
    return ?temperature;
    ?}

    ?
    /**
    ??*?
    @return
    ??
    */
    ?
    public ?String?getTime()?{
    ??
    return ?time;
    ?}

    ?
    /**
    ??*?
    @return
    ??
    */
    ?
    public ?String?getWind()?{
    ??
    return ?wind;
    ?}

    ?
    /**
    ??*?
    @return
    ??
    */
    ?
    public ?String?getWindpower()?{
    ??
    return ?windpower;
    ?}

    ?
    /**
    ??*?
    @param ?string
    ??
    */
    ?
    public ? void ?setTemperature(String?string)?{
    ??temperature?
    = ?string;
    ?}

    ?
    /**
    ??*?
    @param ?string
    ??
    */
    ?
    public ? void ?setTime(String?string)?{
    ??time?
    = ?string;
    ?}

    ?
    /**
    ??*?
    @param ?string
    ??
    */
    ?
    public ? void ?setWind(String?string)?{
    ??wind?
    = ?string;
    ?}

    ?
    /**
    ??*?
    @param ?string
    ??
    */
    ?
    public ? void ?setWindpower(String?string)?{
    ??windpower?
    = ?string;
    ?}

    ?
    /**
    ??*?
    @return
    ??
    */
    ?
    public ? long ?getUpdateTime()?{
    ??
    return ?UpdateTime;
    ?}

    ?
    /**
    ??*?
    @param ?l
    ??
    */
    ?
    public ? void ?setUpdateTime( long ?l)?{
    ??UpdateTime?
    = ?l;
    ?}

    ?
    /**
    ??*?
    @return
    ??
    */
    ?
    public ?String?getState()?{
    ??
    return ?state;
    ?}

    ?
    /**
    ??*?
    @param ?string
    ??
    */
    ?
    public ? void ?setState(String?string)?{
    ??state?
    = ?string;
    ?}

    ?
    /**
    ??*?
    @return
    ??
    */
    ?
    public ?String?getCity()?{
    ??
    return ?city;
    ?}

    ?
    /**
    ??*?
    @param ?string
    ??
    */
    ?
    public ? void ?setCity(String?string)?{
    ??city?
    = ?string;
    ?}

    }


    具體的解析代碼為:

    private ?Weather?parserWeather()? throws ?Exception?{
    ??Weather?w?
    = ? new ?Weather();
    ??
    try ?{

    ???
    // Parser?parser?=
    ???
    // ?new?Parser("file: // localhost/I:/projects/query.html");
    ???Parser?parser? =
    ????
    new ?Parser( " http://weather.news.sohu.com/query.php?city=鎮(zhèn)江 " );
    ???
    ???parser.setEncoding(
    " GBK " );
    ???Node?nodes[]?
    = ?parser.extractAllNodesThatAre(TableTag. class );

    ???TableTag?table?
    = ?(TableTag)?nodes[ 3 ];
    ???
    // temperature
    ???StringNode[]?stringNodes? = ?table.digupStringNode( " 鎮(zhèn)江 " );
    ???StringNode?name?
    = ?stringNodes[ 0 ];
    ???w.setCity(name.toPlainTextString());
    ???CompositeTag?td?
    = ?(CompositeTag)?name.getParent();
    ???CompositeTag?tr?
    = ?(CompositeTag)?td.getParent();
    ???
    int ?columnNo? = ?tr.findPositionOf(td);
    ???TableColumn?nextColumn?
    = ?(TableColumn)?tr.childAt( 5 );
    ???Node?expectedName?
    = ?nextColumn.childAt( 0 );
    ???Node?expectedName2?
    = ?nextColumn.childAt( 2 );
    ???
    // System.out.println(expectedName.getText());
    ???
    // System.out.println(expectedName2.getText());
    ???w.setState(expectedName.getText());
    ???w.setTemperature(expectedName2.getText());
    ???
    // time
    ???stringNodes? = ?table.digupStringNode( " 時間 " );
    ???name?
    = ?stringNodes[ 0 ];
    ???
    // System.out.println(name.toPlainTextString());

    ???String?time?
    =
    ????name
    ?????.toPlainTextString()
    ?????.substring(
    4 ,?name.toPlainTextString().length())
    ?????.trim();
    ???
    // System.out.println(time);
    ???w.setTime(time);
    ???
    // wind
    ???stringNodes? = ?table.digupStringNode( " 風向 " );
    ???name?
    = ?stringNodes[ 0 ];
    ???
    // System.out.println(name.toPlainTextString());

    ???String?wind?
    =
    ????name
    ?????.toPlainTextString()
    ?????.substring(
    4 ,?name.toPlainTextString().length())
    ?????.trim();
    ???
    // System.out.println(wind);
    ???w.setWind(wind);
    ???
    // wind?power
    ???stringNodes? = ?table.digupStringNode( " 風力 " );
    ???name?
    = ?stringNodes[ 0 ];
    ???
    // System.out.println(name.toPlainTextString());

    ???String?windpower?
    =
    ????name
    ?????.toPlainTextString()
    ?????.substring(
    4 ,?name.toPlainTextString().length())
    ?????.trim();
    ???
    // System.out.println(windpower);
    ???w.setWindpower(windpower);

    ???w.setUpdateTime(System.currentTimeMillis());

    ??}?
    catch ?(ParserException?e)?{

    ???e.printStackTrace();
    ??}
    ??
    return ?w;
    ?}


    解析出來的代碼必須做緩存處理,

    private ? static ? long ?TIME_TO_LIVE? = ? 1000 ? * ? 60 ? * ? 60 ? * ? 12 ;

    ?
    private ?Weather?loadWeather()? throws ?Exception?{
    ??Weather?weather?
    = ?weather? = ?(Weather)?cache_.get( " chinaweather " );
    ??
    long ?currentTime? = ?System.currentTimeMillis();
    ??
    if ?(weather? != ? null
    ???
    && ?currentTime? < ?(weather.getUpdateTime()? + ?TIME_TO_LIVE))?{
    ???cache_.remove(
    " chinaweather " );
    ???weather?
    = ? null ;
    ??}

    ??
    if ?(weather? == ? null )?{
    ???
    synchronized ?(cache_)?{
    ????weather?
    = ?parserWeather();
    ????cache_.put(
    " chinaweather " ,?weather);
    ???}
    ??}

    ??
    return ?weather;
    ?}


    posted @ 2007-03-08 06:56 konhon 優(yōu)華 閱讀(2223) | 評論 (0)編輯 收藏

    ?

    import ?org.htmlparser.Node;
    import ?org.htmlparser.NodeFilter;
    import ?org.htmlparser.Parser;
    import ?org.htmlparser.filters.TagNameFilter;
    import ?org.htmlparser.tags.TableTag;
    import ?org.htmlparser.util.NodeList;

    /**
    ?*?<br>
    ?*?標題:?<br>
    ?*?功能概要:?<br>
    ?*?版權(quán):?cityyouth.cn?(c)?2005?<br>
    ?*?公司:上海城市青年網(wǎng)?<br>
    ?*?創(chuàng)建時間:2005-12-21?<br>
    ?*?修改時間:?<br>
    ?*?修改原因:
    ?*?
    ?*?
    @author ?張偉
    ?*?
    @version ?1.0
    ?
    */
    public ? class ?TestYahoo?{
    ????
    public ? static ? void ?testHtml()?{
    ????????
    try ?{
    ????????????String?sCurrentLine;
    ????????????String?sTotalString;
    ????????????sCurrentLine?
    = ? "" ;
    ????????????sTotalString?
    = ? "" ;
    ????????????java.io.InputStream?l_urlStream;
    ????????????java.net.URL?l_url?
    = ? new ?java.net.URL(
    ????????????????????
    " http://sports.sina.com.cn/iframe/nba/live/ " );
    ????????????java.net.HttpURLConnection?l_connection?
    = ?(java.net.HttpURLConnection)?l_url
    ????????????????????.openConnection();
    ????????????l_connection.connect();
    ????????????l_urlStream?
    = ?l_connection.getInputStream();
    ????????????java.io.BufferedReader?l_reader?
    = ? new ?java.io.BufferedReader(
    ????????????????????
    new ?java.io.InputStreamReader(l_urlStream));
    ????????????
    while ?((sCurrentLine? = ?l_reader.readLine())? != ? null )?{
    ????????????????sTotalString?
    += ?sCurrentLine;
    ????????????}
    ????????????System.out.println(sTotalString);

    ????????????System.out.println(
    " ==================== " );
    ????????????String?testText?
    = ?extractText(sTotalString);
    ????????????System.out.println(testText);
    ????????}?
    catch ?(Exception?e)?{
    ????????????e.printStackTrace();
    ????????}

    ????}

    ????
    /**
    ?????*?抽取純文本信息
    ?????*?
    ?????*?
    @param ?inputHtml
    ?????*?
    @return
    ?????
    */
    ????
    public ? static ?String?extractText(String?inputHtml)? throws ?Exception?{
    ????????StringBuffer?text?
    = ? new ?StringBuffer();

    ????????Parser?parser?
    = ?Parser.createParser( new ?String(inputHtml.getBytes(),
    ????????????????
    " 8859_1 " ),? " 8859-1 " );
    ????????
    // ?遍歷所有的節(jié)點
    ????????NodeList?nodes? = ?parser.extractAllNodesThatMatch( new ?NodeFilter()?{
    ????????????
    public ? boolean ?accept(Node?node)?{
    ????????????????
    return ? true ;
    ????????????}
    ????????});
    ????????Node?node?
    = ?nodes.elementAt( 0 );
    ????????text.append(
    new ?String(node.toPlainTextString().getBytes( " 8859_1 " )));
    ????????
    return ?text.toString();
    ????}

    ????
    /**
    ?????*?讀取文件的方式來分析內(nèi)容.?filePath也可以是一個Url.
    ?????*?
    ?????*?
    @param ?resource
    ?????*????????????文件/Url
    ?????
    */
    ????
    public ? static ? void ?test5(String?resource)? throws ?Exception?{
    ????????Parser?myParser?
    = ? new ?Parser(resource);

    ????????
    // ?設(shè)置編碼
    ????????myParser.setEncoding( " GBK " );
    ????????String?filterStr?
    = ? " table " ;
    ????????NodeFilter?filter?
    = ? new ?TagNameFilter(filterStr);
    ????????NodeList?nodeList?
    = ?myParser.extractAllNodesThatMatch(filter);
    ????????TableTag?tabletag?
    = ?(TableTag)?nodeList.elementAt( 11 );
    ????????????
    ????????????System.out.println(tabletag.toHtml());
    ????????????
    ????????????System.out.println(
    " ============== " );

    ????}

    ????
    /*
    ?????*?public?static?void?main(String[]?args)?{?TestYahoo?testYahoo?=?new
    ?????*?TestYahoo();?testYahoo.testHtml();?}
    ?????
    */
    ????
    public ? static ? void ?main(String[]?args)? throws ?Exception?{
    ????????test5(
    " http://sports.yahoo.com/nba/scoreboard " );
    ????}
    }
    posted @ 2007-03-08 06:50 konhon 優(yōu)華 閱讀(1593) | 評論 (0)編輯 收藏

         摘要: 最近搞一個扣網(wǎng)頁內(nèi)容的SessionBean,需要模擬客戶端post提交,然后得到servlet返回的結(jié)果。采用Jakarta的HttpClient API解決之.HttpClient擴展和增強了標準java.net包,是一個內(nèi)容廣泛的代碼庫,功能極其豐富,能夠構(gòu)造出各種使用HTTP協(xié)議的分布式應用,或者也可以嵌入到現(xiàn)有應用,為應用增加訪問HTTP協(xié)議的能力 要求:1:CLASSPATH中有...  閱讀全文
    posted @ 2007-03-07 21:51 konhon 優(yōu)華 閱讀(3773) | 評論 (0)編輯 收藏


    服務器:
    1.jsp
    <body>
    <form name="_ctl0" method="post" action="TestFileManager.aspx" id="_ctl0" enctype="multipart/form-data">
    <input type="hidden" name="__VIEWSTATE" value="dDwyNTIzNjA5NDU7Oz7rsE3eBYzQHDVtl+aTn96MvQW6PQ==" />
    <p>
    <input name="uploadfile1" id="uploadfile1" type="file" size="49" />
    <input type="submit" name="Button1" value="?" id="Button1" />
    </p>
    <p>
    <span id="Label1" style="width:459px;"></span>
    </p>
    <!-- Insert content here -->
    </form>
    </body>
    客戶端:
    首先創(chuàng)建一個到服務器http的請求
    HttpRequest request = new HttpRequest("http://服務器/1.jsp");
    第一次使用的是GET方式
    request.setMethod("GET");
    緊接著進行一些請求的屬性設(shè)置
    request.setRequestHeader("Cache-Control", "no-cache");
    這里保持連接,因為后面還要發(fā)送數(shù)據(jù)到服務器呢
    request.setRequestHeader("Connection", "Keep-Alive");
    下面是一些無關(guān)緊要的屬性設(shè)置了。
    request.setRequestHeader("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
    request.setRequestHeader("Accept-Encoding", "gzip, deflate");
    request.setRequestHeader("Accept-Language", "en-au");
    request.setRequestHeader("Referer", "http://服務器/1.jsp");
    request.setRequestHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3215; .NET CLR 1.0.3705)");
    構(gòu)造好了連接請求,然后連接
    request.connect();
    緊接著提取Cookie值,在后文的post中可以用到。
    String strCookie = request.getResponseHeader("Set-Cookie");
    strCookie = strCookie.substring(0,strCookie.indexOf(";"));
    下面通過循環(huán)查找,提取__VIEWSTATE的值
    for ( int i = 0; i < nlist.getLength(); i++) {
    node = nlist.item(i);
    strName = getNodeAttributeValue(node,"name");
    if ( strName.equals("__VIEWSTATE") ) {
    strValue = getNodeAttributeValue(node,"value");
    break;
    }
    }
    往服務器組織發(fā)送數(shù)據(jù)
    DataOutputStream dos = new DataOutputStream(request.getOutputStream());
    dos.writeBytes("-----------------------------"+strBoundary);//這是每個要被發(fā)送數(shù)據(jù)間的間隔
    dos.writeBytes(" Content-Disposition: form-data; name="__VIEWSTATE"");
    dos.writeBytes(" "+strValue);
    dos.writeBytes(" -----------------------------"+strBoundary);
    這里面是發(fā)送文件的部分
    dos.writeBytes(" Content-Disposition: form-data; name="uploadfile1"; filename="" + strFileName + """);
    dos.writeBytes(" Content-Type: text/xml");
    dos.writeBytes(" ");
    dos.writeBytes(new String(data));
    dos.writeBytes(" -----------------------------"+strBoundary);
    dos.writeBytes(" Content-Disposition: form-data; name="Button1"");
    dos.writeBytes(" 上傳");
    dos.writeBytes(" -----------------------------"+strBoundary+"--");
    dos.writeBytes(" ");
    dos.close();
    posted @ 2007-03-07 20:14 konhon 優(yōu)華 閱讀(4266) | 評論 (1)編輯 收藏

    2007年1月30日 #

         摘要: 2?/**???3??*?//FileOperate.java??4??*?文件的各種操作??5??*?楊彩?http://blog.sina.com.cn/m/yangcai??6??*?文件操作?1.0??7??*/???8????9?//package?common;??10???11?import?java.io.*;??12???13?public?class?FileOperate?1...  閱讀全文
    posted @ 2007-01-30 06:25 konhon 優(yōu)華 閱讀(1168) | 評論 (0)編輯 收藏

    2006年12月17日 #

    最近在項目中使用 Spring Hibernate 進行開發(fā),有感于 Criteria 比較好用,在查詢方法設(shè)計上可以靈活的根據(jù) Criteria 的特點來方便地進行查詢條件的組裝。所以現(xiàn)在對 Hibernate Criteria 深入研究一下?!?/span> Hibernate Reference 》及網(wǎng)上其它一些資料對 Criteria 已經(jīng)做了很多介紹。本文主要是從 Criteria 的結(jié)構(gòu)入手來進行分析。

    ?????? 如圖 1 。 Hibernate 設(shè)計了 CriteriaSpecification 作為 Criteria 的頂級接口,其下面提供了 Criteria DetachedCriteria

    Criteria DetachedCriteria 的主要區(qū)別在于創(chuàng)建的形式不一樣, Criteria 是在線的,所以它是由 Hibernate Session 進行創(chuàng)建的;而 DetachedCriteria 是離線的,創(chuàng)建時無需 Session , DetachedCriteria 提供了 4 個靜態(tài)方法 forClass(Class) forEntityName(Name) 進行 DetachedCriteria 實例的創(chuàng)建。 Spring 的框架提供了

    getHibernateTemplate().findByCriteria(detachedCriteria) 方法可以很方便地根據(jù)

    DetachedCriteria 來返回查詢結(jié)果。

    如圖 1 , Criteria DetachedCriteria 均可使用 Criterion Projection 設(shè)置查詢條件。可以設(shè)置 FetchMode( 聯(lián)合查詢抓取的模式 ) ,設(shè)置排序方式。對于 Criteria 還可以設(shè)置 FlushModel (沖刷 Session 的方式)和 LockMode (數(shù)據(jù)庫鎖模式)。

    下面就對 Criterion Projection 進行詳細說明。

    ???????

    1

    ?

    ?????? Criterion Criteria 的查詢條件。

    Criteria 提供了 add(Criterion criterion) 方法來添加查詢條件。圖 2 Criterion 的結(jié)構(gòu)圖。 Criterion 接口的主要實現(xiàn)包括: Example Junction SimpleExpression 。而 Junction 的實際使用是它的兩個子類 conjunction disjunction ,分別是使用 AND OR 操作符進行來聯(lián)結(jié)查詢條件集合。

    Criterion 的實例可以通過 Restrictions 工具類來創(chuàng)建, Restrictions 提供了大量的靜態(tài)方法,如 eq (等于)、 ge (大于等于)、 between 等來方法的創(chuàng)建 Criterion 查詢條件

    SimpleExpression 實例)。除此之外, Restrictions 還提供了方法來創(chuàng)建 conjunction disjunction 實例,通過往該實例的 add(Criteria) 方法來增加查詢條件形成一個查詢條件集合。

    至于 Example 的創(chuàng)建有所不同, Example 本身提供了一個靜態(tài)方法 create(Object entity) ,即根據(jù)一個對象(實際使用中一般是映射到數(shù)據(jù)庫的對象)來創(chuàng)建。然后可以設(shè)置一些過濾條件:

    Example exampleUser =Example.create(u)

    .ignoreCase() // 忽略大小寫

    .enableLike(MatchMode.ANYWHERE);

    // String 類型的屬性,無論在那里值在那里都匹配。相當于 %value%

    ?
    2

    ??????

    Project 主要是讓 Criteria 能夠進行報表查詢,并可以實現(xiàn)分組。 Project 主要有 SimpleProjection ProjectionList Property 三個實現(xiàn)。其中 SimpleProjection ProjectionList 的實例化是由內(nèi)建的 Projections 來完成,如提供的 avg 、 count max 、 min 、 sum 可以讓開發(fā)者很容易對某個字段進行統(tǒng)計查詢。

    ?????? Property 是對某個字段進行查詢條件的設(shè)置,如通過

    ????? Porperty.forName(“color”).in(new String[]{“black”,”red”,”write”}); 則可以創(chuàng)建一個 Project 實例。通過 criteria add(Project) 方法加入到查詢條件中去。

    ?
    3

    ??????

    ?????? 使用 Criteria 進行查詢,主要要清晰的是 Hibernate 提供了那些類和方法來滿足開發(fā)中查詢條件的創(chuàng)建和組裝,其結(jié)構(gòu)層次如何。這樣使用起來便可得心應手。

    posted @ 2006-12-17 03:18 konhon 優(yōu)華 閱讀(1530) | 評論 (1)編輯 收藏

    僅列出標題  下一頁
    主站蜘蛛池模板: 夫妻免费无码V看片| 国产精品成人免费福利| 免费日本一区二区| 99在线视频免费| 在线观看特色大片免费视频| 国产嫩草影院精品免费网址| 亚洲伊人成无码综合网| 久久国产亚洲高清观看| 国产亚洲精品VA片在线播放| 日本激情猛烈在线看免费观看| 亚洲国产AV无码一区二区三区 | 亚洲人成影院午夜网站| 亚洲中文无码卡通动漫野外| 特a级免费高清黄色片| 久章草在线精品视频免费观看| 91香焦国产线观看看免费| 女人毛片a级大学毛片免费| 亚洲国产精品人人做人人爱| 婷婷久久久亚洲欧洲日产国码AV| 亚洲一区二区免费视频| 污污视频免费观看网站| 99热这里有免费国产精品| 日本免费中文字幕在线看| 精品亚洲永久免费精品| 99999久久久久久亚洲| 国产精品免费αv视频| 成年人网站免费视频| 亚洲精品国产成人影院| 亚洲熟妇色自偷自拍另类| 黄页网站在线免费观看| 5555在线播放免费播放| 成人亚洲网站www在线观看| 色播亚洲视频在线观看| 污污免费在线观看| 国产情侣激情在线视频免费看| 日本一道本高清免费| 亚洲国产精品久久66| 免费在线观看一区| 在线观看特色大片免费视频| 亚洲精品乱码久久久久久蜜桃不卡| 国产成人亚洲精品|