zoukankan      html  css  js  c++  java
  • kbmMemTable关于内存表的使用,以及各种三层框架的评价

    关于内存表的使用(kbmMemTable)

    关于内存表的使用说明
    一、 Delphi使用内存表
    1.1 Delphi创建内存表步骤:
    1. 创建一个Ttable实例。
    2. 设置一个DataBaseName为一个目录或是已有的数据库别名。
    3. 指定TableName的值。
    4.设置TableType属性指明要创建的数据库表类型。(如果此属性为ttDefault表示数据库类型与TableName指定值的扩展名对应)。
    5. 调用TTable.FidldDefs对象的Add方法向数据库表中添加字段。Add有4个参数:
    字段名:string。
    字段类型:TfieldType。
    字段大小:Word。一般只对String和Memo类型使用。
    字段是否NotNull: Boolean。
    6. 使用TTable.IndexDefs.Add()方法定义索引。Add有三个参数:
    索引名:string;
    索引字段名:string;
    索引类型:TIndexOptions;
    7. 调用TTable的CreateTable。这种方法适用于本地表。SQL表要用TQuery来创建。
    代码如下:
    var
    MemTable: TTable;
    begin
    with MemTable.Create(Self) do
    begin
    DatabaseName := 'c:Temp';
    TableName := 'Test';
    TableType := ttParadox;
    with FieldDefs do
    begin
    Add('Age', ftInteger, 0, True);
    Add('Name', ftString, 25, False);
    Add('Weight', ftFloat, 0, False);
    end;
    IndexDefs.Add('', 'Age', [ixPrimary, ixUnique]);
    CreateTable;
    end;
    end;
    二、 kbmMemTable使用简述
    2.1 kbmMemTable创建步骤:
    1. 创建一个kbmMemTable对象实例。
    2. 调用kbmMemTable.FidldDefs对象的Add方法向数据库表中添加字段。Add的方法和Delphi相同。
    3. 使用kbmMemTable.IndexDefs.Add()方法定义索引。Add的方法和Delphi相同。
    4. 调用kbmMemTable的CreateTable。
    重要的区别:因为kbmMemTable不需要BDE的支持。所以不要指明DatabaseName, TableName和TableType三个属性。
    代码如下:
    with kbmMemTable1 do
    begin
    with kbmMemTable1.FieldDefs do
    begin
    Clear;
    Add('Period', ftInteger, 0, false);
    Add('VALUE', ftLargeInt, 0, false);
    Add('BytesField', ftBytes, 20, false);
    Add('Color', ftInteger, 0, false);
    Add('Date', ftDate, 0, false);
    Add('Memo', ftMemo, 0, false);
    Add('AutoInc', ftAutoInc, 0, false);
    end;
    with kbmMemTable1.IndexDefs do
    begin
    Clear;
    Add('Index1', 'VALUE', []);
    end;
    CreateTable;
    end;
    三、与Delphi创建内存表的对比
    3.1主从表功能
    kbmMemTable可以象其它TDataSet一样,通过设置MasterSource和MasterField来简单的完成主从表的操作。
    3.2 SQL功能
    没有发现kbmMemTable可以支持SQL语句的操作。它提供按字段排序和对排序字段的查找功能。
    三、 kbmMemTable特点
    从其它TDataSet得到数据。
    代码如下:
    LoadFromDataSet(Table1, [mtcpoStructure, mtcpoProperties]);
    这样kbmMemTable就完全得到来自一个DataSet对象中的全部数据.
    保存和载入内存表中数据的功能
    Delphi的TTable不提供SaveToFile功能。
    kbmMemTable提供保存到文件的功能,保存的文件有两种格式:
    Options: TkbmMemTable.SaveFlags;
    1. 二进制格式。kbmMemTable.SaveToBinaryFile('c: est.bin', Options).
    kbmMemTable1.LoadFromBinaryFile('c: est.bin')
    2. .csv格式。kbmMemTable.SaveToFile('c: est.csv', Options);
    kbmMemTable1.LoadFromFile('c: est.csv')
    (一种Excel支持的文档格式)打开后的内容如下:
    @@FILE VERSION@@ 200
    @@TABLEDEF START@@
    Period=Integer,0,"Period","",10
    VALUE=LargeInt,0,"VALUE","",15
    BytesField=Bytes,20,"BytesField","",10
    Color=Integer,0,"Color","",10
    Date=Date,0,"Date","",10
    Memo=Memo,0,"Memo","",10
    AutoInc=AutoInc,0,"AutoInc","",10
    CALC=String,20,"CALC","",20
    @@TABLEDEF END@@
    Period VALUE BytesField Color Date Memo AutoInc CALC
    1 198 0 02/11/2001 This is a memo%n2001-11-2 10:19:52 1 0 1-二月
    2 196 3 03/11/2001 This is a memo%n2001-11-2 10:19:52 2 1 2-三月
    在文档的头部份描述了表的字段结构,在下面则是数据区域.
    以下代码用ClientDataSet建立内存表,包含Field1和Field2两个字段,在Field1上建索引:
    with ClientDataSet1 do
    begin
    //添加Integer类型的字段Field1
    with FieldDefs.AddFieldDef do
    begin
    DataType := ftInteger;
    Name := 'Field1';
    end;
    //添加string类型的字段Field2
    with FieldDefs.AddFieldDef do
    begin
    DataType := ftString;
    Size := 10;
    Name := 'Field2';
    end;
    //在Field1上建索引
    with IndexDefs.AddIndexDef do
    begin
    Fields := 'Field1';
    Name := 'IntIndex';
    end;
    //创建内存表
    CreateDataSet;
    end;

    》》》》》》》》》》》》》》》》》

    KbmMemTable是一款高效且强大的内存表控件,内存表顾名思义其最大的优势就是速度,KbmMemTable不仅完美地实现了高效的特征,同时,最新版本还支持索引、SQL语句等高级用法。其用法超简单,基本用法和ClientDataSet一致,以下是我简单的应用示例,实现了增删改查等基本功能:


    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Grids, DBGrids, DB, StdCtrls, kbmMemTable;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        DataSource1: TDataSource;
        DBGrid1: TDBGrid;
        Button2: TButton;
        Button3: TButton;
        Button4: TButton;
        Button5: TButton;
        Button6: TButton;
        Button7: TButton;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure Button4Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
        procedure Button5Click(Sender: TObject);
        procedure Button6Click(Sender: TObject);
        procedure Button7Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
     
    var
      Form1: TForm1;
      kbmMemTable1 : TkbmMemTable;
      Id:Integer;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      //建表
      kbmMemTable1.FieldDefs.Clear;
      kbmMemTable1.FieldDefs.Add('Id', ftInteger, 0, False);
      kbmMemTable1.FieldDefs.Add('Value', FtString, 20, False);
      kbmMemTable1.FieldDefs.Add('Time', ftDateTime, 0, False);
      kbmMemTable1.IndexDefs.Add('Index1','Id',[]);//定义索引
      kbmMemTable1.CreateTable;
      kbmMemTable1.Active := True;
    end;
     
    procedure TForm1.Button2Click(Sender: TObject);
    var
      fld_Id:TIntegerField;
      fld_Value:TStringField;
      fld_Time:TDateTimeField;
      i:Integer;
    begin
      //插入
      with kbmMemTable1 do
      begin
        DisableControls; //切断数据感知控件
        try
          Open; //打开
          //定义Field
          fld_Id:=TIntegerField(FieldByName('Id'));
          fld_Value:=TStringField(FieldByName('Value'));
          fld_Time:=TDateTimeField(FieldByName('Time'));
          for i := 0 to 9 do
          begin
            Inc(Id);
            Append; //附加数据
            //赋值
            fld_Id.AsInteger := Id;
            fld_Value.AsString := 'Hello PFeng!'+inttostr(Id);
            fld_Time.AsDateTime := Now;
            Post; //确定
          end;
          UpdateIndexes;//更新索引
        finally
          EnableControls; //连接数据感知控件
        end;
      end;
    end;
     
    procedure TForm1.Button3Click(Sender: TObject);
    var
      fld_Id:TIntegerField;
      fld_Value:TStringField;
      fld_Time:TDateTimeField;
    begin
      //更新
      with kbmMemTable1 do
      begin
        Open;
        fld_Id:=TIntegerField(FieldByName('Id'));
        fld_Value:=TStringField(FieldByName('Value'));
        fld_Time:=TDateTimeField(FieldByName('Time'));
        if Locate('Id',5,[]) then
        begin
          Edit;
          fld_Value.AsString := '内容被修改';
          fld_Time.AsDateTime := Now;
          Post;
        end;
      end;
    end;
     
    procedure TForm1.Button4Click(Sender: TObject);
    var
      fld_Id:TIntegerField;
      fld_Value:TStringField;
      fld_Time:TDateTimeField;
    begin
      //查询
      with kbmMemTable1 do
      begin
        Open;
        fld_Id:=TIntegerField(FieldByName('Id'));
        fld_Value:=TStringField(FieldByName('Value'));
        fld_Time:=TDateTimeField(FieldByName('Time'));
        if Locate('Id',5,[]) then
        ShowMessage(fld_Value.AsString);
        //还可以用FindKey实现,结合索引速度更快
        // kbmMemTable1.IndexFieldNames:='Id';
        // if kbmMemtable1.FindKey([5]) then ...
      end;
    end;
     
    procedure TForm1.Button5Click(Sender: TObject);
    var
      fld_Id:TIntegerField;
      fld_Value:TStringField;
      fld_Time:TDateTimeField;
    begin
      //删除
      with kbmMemTable1 do
      begin
        Open;
        fld_Id:=TIntegerField(FieldByName('Id'));
        fld_Value:=TStringField(FieldByName('Value'));
        fld_Time:=TDateTimeField(FieldByName('Time'));
        if Locate('Id',5,[]) then
        begin
          Delete;
          UpdateIndexes;
        end;
      end;
    end;
     
    procedure TForm1.Button6Click(Sender: TObject);
    var
      fld_Id:TIntegerField;
      fld_Value:TStringField;
      fld_Time:TDateTimeField;
      id:Integer;
    begin
      //循环比较最小值
      with kbmMemTable1 do
      begin
        Open;
        fld_Id:=TIntegerField(FieldByName('Id'));
        fld_Value:=TStringField(FieldByName('Value'));
        fld_Time:=TDateTimeField(FieldByName('Time'));
        DisableControls;
        try
          First;
          id := fld_Id.AsInteger;
          while not Eof do
          begin
            if id > fld_Id.AsInteger then
            id := fld_Id.AsInteger;
            Next;
          end;
          Locate('Id',id,[]);
        finally
          EnableControls;
        end;
      end;
    end;
     
    procedure TForm1.Button7Click(Sender: TObject);
    begin
      //清空
      kbmMemTable1.EmptyTable;
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      kbmMemTable1 := TkbmMemTable.Create(Self);
      DataSource1.DataSet := kbmMemTable1;
    end;
     
    end.

    http://www.pfeng.org/archives/372

    》》》》》》》》》》》》》》》》》》》》》》》》》》

    前端时间一直在研究三层通讯框架,计划封装一套稳定性较好的远程数据库服务接口,前期的方案主要有以下几种:
    1,改造自己写的indy+压缩xml流三层应用项目
    2,基于MMZ asio远程数据库项目进一步完善
    3,寻找并测其他相对成熟的三层通讯框架,知道的有:QuickBurro、RemoteAdo、Middle ADO System、dbIOCP、DataSnap、ASTA、Remobject SDK、kbmMW,接下来我将就我对以上三层框架的浅薄认识一一说明。
    首先说方案1,在早些时候为了实现远程数据库与本地数据库的同步,我写过一套基于indy+压缩xml流的C/S应用,客户端的请求封装在xml中,发送到服务端,服务端在数据库中执行后,把执行结果(例如结果集)拼装成xml再压缩成流,返回到客户端,虽然当时基本上满足了需求,但项目有着很大的局限:并发性差、效率低、通讯不稳定等,一旦网络条件稍差,服务端就会报异常,想想那段维护服务端软件的日子简直就是噩梦,如果本次项目仍然采用这种思路,我需要去改进很多地方,比如数据库连接池、多线程、数据校验、底层通讯等,在有限的时间里很难去把多个方面都做稳定,权衡后,觉得自己应该站在巨人的肩膀上来实现自己的业务逻辑,于是放弃了这个方案。
    方案2,ASIO(http://think-async.com/)是C++的一个强大的通讯库,据说是工业级别的,我的一个Delphi技术群(群号:15637473)的群主把ASIO编译成了一个DLL动态库,然后又结合unidac、连接池等,封装了一个简单的三层通讯框架MMZ ASIO(http://mmz-asio4delphi.googlecode.com),我在早些时候用这个框架做了几个小项目,感觉比较简单,效率也很高,但是有几个bug迟迟得不到解决(客户端不能主动断开、服务端容易报线程异常等),给群主写邮件,群主说他现在很忙,没时间解决这些问题,而以我个人的水平,又很难去从核心代码上做改动。目前有几个忠实的asio爱好者还在深入研究(群号:91684553),相信有朝一日会稳定起来,考虑到时间成本,同样放弃了这个方案。


    最后,最佳的选择就是选择一款成熟的三层框架,在此基础上做二次开发,于是从网上搜了好几天时间,了解各个框架的情况,首先基于成本和稳定性的考虑放弃了国产框架:
    1,QuickBurro(http://www.quickburro.com/),樵夫的作品,到目前还一直在做升级,具体价格参见2,http://www.quickburro.com/orders.html,授权方式比较宽松,免费版的用户数有限制(好像是16个?不确定)。
    3,RemoteAdo(http://www.remoteado.cn/index.html),了解的不多,但是就从网站上来介绍来看,功能比较局限,当然,也是收费的。
    4,Middle ADO System(http://www.middle-ado.com/),厦门一家公司的产品,同样了解的不多,价格不详,功能也比较局限。
    5,dbIOCP(群号:35916846),楠楠的作品,据说效率很高(IOCP不多说,网上一搜便知道),价格好像是3000/套,带源码,升级不是很频繁,网上的免费1.6版连楠楠自己都说已经很久了,我看群里很多讨论2.4版本的,楠楠同样自己说性能没法和3.x版本的比,新版的架构都变了,效率说的很神,但是个人作品,在没有很好地推广的情况下,3000刀个人感觉有点儿贵。


    再来说其他的几个著名框架:
    1,DataSnap,这个其实很多人都比较熟悉,它是Delphi的三层框架MIDAS的延续,李维在多次讲座和个人书籍中都强烈推荐,而且国外社区很多人都提到它,估计能力不俗,但是网上褒贬不一,个人深入了解的不够。
    2,ASTA(http://www.astatech.com/products/asta3/),也是一个老牌的三层框架,据说在200x年的时候很火,但是开发者后续升级不给力,单从网站首页上的新闻就让人很惊讶:ASTA 3.1 is here and it’s HOT with support for Delphi 2006…当然,如果你还在用D2007以下版本做开发的话,可以试试,但是我个人觉得缺乏后续的SAU(Service and Update),心理上总是不踏实。价格不详,但是网上Full Source版本的一搜一大把。
    3,Remobject SDK(http://www.remobjects.com/default.aspx),其实我对这个框架的印象很好,因为之前计数群里已经基于它做了很多成熟的项目,而且在讨论过程中口碑也相当不错,而且现在for XE2的版本网上也很好找到,建议有兴趣的人可以深入研究以下。
    4,KbmMW(http://www.components4programmers.com/products/kbmmw/index.htm),说到本文的重点了,KbmMW在国内圈子里能够得到认可,很大程度上得益于窑主xalion详细的博文教程(http://www.cnblogs.com/xalion/),作者Kim Madsen对中国国情的充分考虑(对中国程序员价格上优惠25%),KbmMW在国外社区很火,国内可能很多人对kbmMemTable都不陌生,而KbmMW也是基于kbmMemTable做的封装。我对KbmMW最大的认可就是其开放的架构思路:通讯控件支持Indy(9和10)、Synapse、DxSock,数据库控件支持ADO和Unidac等、当然还有其他的加密、压缩等均支持开源的第三方控件,给开发人员了很大自由度。作者的热心也让我很感动,每次遇到问题,白天我在StackOverFlow上提问,夜里Kim就在上面认真回答。
    当然还有很多其他的优秀框架(据说Dephi的三次框架解决方案是所有开发语言中最多的),比如德国的RTC(http://www.realthinclient.com/)据说也是很不错的,有兴趣的可以自己去了解下,当我了解了KbmMW之后,我觉得,KbmMW是我最好的选择。

    http://blog.csdn.net/zisongjia/article/details/72869734

  • 相关阅读:
    【洛谷P4887】【模板】莫队二次离线(第十四分块(前体))
    查询数据库表大小
    java程序使用ssl证书连接mysql
    win32- 函数运行速度测试
    回调函数是嘛东西
    win32-读取控制台中所有的字符串
    关于 websocket 的一些学习
    idea下载地址
    ida 重新定义
    P1650 田忌赛马(贪心)
  • 原文地址:https://www.cnblogs.com/findumars/p/7062224.html
Copyright © 2011-2022 走看看