问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

Delphi的kbmMemTable控件与AdoQuery有什么区别

发布网友 发布时间:2022-04-30 10:52

我来回答

2个回答

懂视网 时间:2022-04-30 15:13

Arena { public: Arena(); ~Arena(); // Return a pointer to a newly allocated memory block of "bytes" bytes. char* Allocate(size_t bytes); // Allocate memory with the normal alignment guarantees provided by malloc char* AllocateAligned(size_t bytes); // Returns an estimate of the total memory usage of data allocated // by the arena (including space allocated but not yet used for user // allocations). size_t MemoryUsage() const { return blocks_memory_ + blocks_.capacity() * sizeof(char*); } ...... }

Arena实际上就是一个Allocator,在Heap上执行内存管理,其好处有二:

1. 提高程序性能:减少Heap调用次数,专有Arena统一分配后返回到应用层。

2. 统一内存管理:分配后无需执行dealloc,当Arena对象释放时,统一释放由其创建的所有内存。

当然,这是个功能并不完善的Allocator,但适用于MemTable的特点3.a。

 class Slice {
 public:
  ......
 private:
 const char* data_;
 size_t size_;

 // Intentionally copyable
 }; 

Slice的含义和其名称一致,代表了一个数据块,data_为数据地址,size_为数据长度。

Slice一般和Arena配合使用,其仅保持了数据信息,并未拥有数据的所有权。而数据在Arena对象的整个声明周期内有效。

Slice在LevelDB中一般用于传递Key、Value或编解码处理后的数据块。

和string相比,Slice具有的明显好处包括:避免不必要的拷贝动作、具有比string更丰富的语义(可包含任意内容)。

class MemTableIterator : public Iterator{......}
MemTableIterator为SkipList::Iterator的封装类,简单,略。

在LevelDB中,共有三种Key:

1. User Key: 用户传入的Key内容,下表中的Part2.

2. Internal Key: LevelDB内部存储时使用的Key,下表中的Part2-Part3。除User Key外,还包括了本次操作的序号及操作类型信息。

3. MemTable Key: 下表中的Part1-Part3。

Part 1  Part 2 Part 3 Part 4 Part 5
Key Size + 8 Key Content Seq Number << 8 | ValueType Value Size  Value Content

表1

最后一个比较重要的类InternalKeyComparator,这是Internal Key的比较器,其中的关键在于Compare方法:

 int InternalKeyComparator::Compare(const Slice& akey, const Slice& bkey) const {
 // Order by:
 // increasing user key (according to user-supplied comparator)
 // decreasing sequence number
 // decreasing type (though sequence# should be enough to disambiguate)
 int r = user_comparator_->Compare(ExtractUserKey(akey), ExtractUserKey(bkey));  //首先调用user comparator进行键值比较
 if (r == 0) {
  const uint64_t anum = DecodeFixed64(akey.data() + akey.size() - 8);
  const uint64_t bnum = DecodeFixed64(bkey.data() + bkey.size() - 8);
  if (anum > bnum) {  //序号及类型比较比较,即操作版本号比较。较新的操作版本号较高,比较器认为较新的版本<较老的版本或者老版本>新版本
  r = -1;
  }
  else if (anum < bnum) {
  r = +1;
  }
 }
 return r;
 }

值得注意的是序号及类型的比较,实际上由于任意操作序号的唯一性,类型比较时非必须的。这里同时进行了类型比较也是出于性能的考虑(减少了从中分离序号、类型的工作)。

序号或者说版本号采用的是降序原则,这导致的效果是,比较器认为老版本>新版本,为什么不是新版本>老版本呢?因为Snapshot机制的支持,当用户想查看Snapshot(快照)时,希望找到指定版本号之前的数据。

 

有了以上储备后,再来看MemTable就比较简单了,首先看插入方法Add:

 void MemTable::Add(SequenceNumber s, ValueType type, const Slice& key, const Slice& value) 
 {
 // Format of an entry is concatenation of:
 // key_size : varint32 of internal_key.size()
 // key bytes : char[internal_key.size()]
 // value_size : varint32 of value.size()
 // value bytes : char[value.size()]
 size_t key_size = key.size();
 size_t val_size = value.size();
 size_t internal_key_size = key_size + 8;
 //总长度
 const size_t encoded_len =
  VarintLength(internal_key_size) + internal_key_size +
  VarintLength(val_size) + val_size;
 char* buf = arena_.Allocate(encoded_len);
 //Key
 char* p = EncodeVarint32(buf, internal_key_size);
 memcpy(p, key.data(), key_size);
 p += key_size;
 //Seq Number + Value Type
 EncodeFixed64(p, (s << 8) | type);
 p += 8;
 //Value
 p = EncodeVarint32(p, val_size);
 memcpy(p, value.data(), val_size);

 assert((p + val_size) - buf == encoded_len);
 
 table_.Insert(buf);
 }

以下几点备注:

1. MemTable将用户数据编码为表1的结构进行存储,其中Part1、Part4采用了Variant32的存储方式,Part3则采用Fixed64。LevelDB中何处采用Variant、何处采用Fixed的方式,规律尚未摸清,想必也和性能有关?

2. MemTable不提供删除方法,客户端的删除动作将被转换为一次ValueType为Deletion的添加动作,等MemTable需要被Compaction到磁盘时方执行真正的删除。

3. 数据编码完毕后,将数据插入到SkipList中(table_)。

再来看Get方法:

 1 bool MemTable::Get(const LookupKey& key, std::string* value, Status* s) 
 2  {
 3  Slice memkey = key.memtable_key(); 
 4 
 5  Table::Iterator iter(&table_);
 6  iter.Seek(memkey.data());
 7 
 8  if (iter.Valid()) {
 9  // entry format is:
10  // klength varint32
11  // userkey char[klength - 8]
12  // tag uint64
13  // vlength varint32
14  // value char[vlength]
15  // Check that it belongs to same user key. We do not check the
16  // sequence number since the Seek() call above should have skipped
17  // all entries with overly large sequence numbers.
18  const char* entry = iter.key();
19   uint32_t key_length;
20  const char* key_ptr = GetVarint32Ptr(entry, entry + 5, &key_length);
21  if (comparator_.comparator.user_comparator()->Compare(
22   Slice(key_ptr, key_length - 8), key.user_key()) == 0) 
23   {
24   // Correct user key
25   const uint64_t tag = DecodeFixed64(key_ptr + key_length - 8);
26   switch (static_cast<ValueType>(tag & 0xff)) {
27   case kTypeValue: {
28   Slice v = GetLengthPrefixedSlice(key_ptr + key_length);
29   value->assign(v.data(), v.size());
30   return true;
31   }
32   case kTypeDeletion:
33   *s = Status::NotFound(Slice());
34   return true;
35   }
36   }
37  }
38  return false;
39 }

Line3的memtable_key即表1中Part1-Part3内容,其中Seq Number在指定了Snapshot时为Snapshot的Seq Number,否则为最后一次更新的Seq Nmuber。

Line6调用SkipList的Seek方法定位,随后校验找到的iter是否和指定的key一致,如果一致并且ValueType为kTypeValue,返回找到的数据,否则查找失败。

 

小结:

1. 性能是第一要义:Arena、Slice、甚至数据编码的Variant都是为此准备的。

2. Seq Number在LevelDB中扮演了重要角色,在数据查找、Snapshot中至关重要。

3. MemTable是SkipList的必要封装。

LevelDB源码之二MemTable

标签:

热心网友 时间:2022-04-30 12:21

关于内存表的使用(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:\test.bin', Options). kbmMemTable1.LoadFromBinaryFile('c:\test.bin') 2. .csv格式。kbmMemTable.SaveToFile('c:\test.csv', Options); kbmMemTable1.LoadFromFile('c:\test.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一致,以下是我简单的应用示例,实现了增删改查等基本功能:

Delphi <wbr>: <wbr>kbmMemTable关于内存表的使用

unit Unit1

interface

use

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, Grids, DBGrids, DB, StdCtrls, kbmMemTable

type

TForm1 = class(TForm)

Button1: TButto

DataSource1: TDataSource

DBGrid1: TDBGrid

Button2: TButto

Button3: TButto

Button4: TButto

Button5: TButto

Button6: TButto

Button7: TButto

rocere Button1Click(Sender: TObject)

rocere FormCreate(Sender: TObject)

rocere Button2Click(Sender: TObject)

rocere Button4Click(Sender: TObject)

rocere Button3Click(Sender: TObject)

rocere Button5Click(Sender: TObject)

rocere Button6Click(Sender: TObject)

rocere Button7Click(Sender: TObject)

rivate

{ Private declarations }

ublic

{ Public declarations }

end

var

Form1: TForm1

kbmMemTable1 : TkbmMemTable

Id:Integer

implementatio

{$R *.dfm}

rocere TForm1.Button1Click(Sender: TObject)

egi

//建表

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

rocere TForm1.Button2Click(Sender: TObject)

var

fld_Id:TIntegerField

fld_Value:TStringField

fld_Time:TDateTimeField

i:Integer

egi

//插入

with kbmMemTable1 do

egi

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

egi

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

rocere TForm1.Button3Click(Sender: TObject)

var

fld_Id:TIntegerField

fld_Value:TStringField

fld_Time:TDateTimeField

egi

//更新

with kbmMemTable1 do

egi

Ope

fld_Id:=TIntegerField(FieldByName('Id'))

fld_Value:=TStringField(FieldByName('Value'))

fld_Time:=TDateTimeField(FieldByName('Time'))

if Locate('Id',5,[]) the

egi

Edit

fld_Value.AsString := '内容被修改'

fld_Time.AsDateTime := Now

Post

end

end

end

rocere TForm1.Button4Click(Sender: TObject)

var

fld_Id:TIntegerField

fld_Value:TStringField

fld_Time:TDateTimeField

egi

//查询

with kbmMemTable1 do

egi

Ope

fld_Id:=TIntegerField(FieldByName('Id'))

fld_Value:=TStringField(FieldByName('Value'))

fld_Time:=TDateTimeField(FieldByName('Time'))

if Locate('Id',5,[]) the

ShowMessage(fld_Value.AsString)

//还可以用FindKey实现,结合索引速度更快

// kbmMemTable1.IndexFieldNames:='Id'

// if kbmMemtable1.FindKey([5]) then ...

end

end

rocere TForm1.Button5Click(Sender: TObject)

var

fld_Id:TIntegerField

fld_Value:TStringField

fld_Time:TDateTimeField

egi

//删除

with kbmMemTable1 do

egi

Ope

fld_Id:=TIntegerField(FieldByName('Id'))

fld_Value:=TStringField(FieldByName('Value'))

fld_Time:=TDateTimeField(FieldByName('Time'))

if Locate('Id',5,[]) the

egi

Delete

UpdateIndexe

end

end

end

rocere TForm1.Button6Click(Sender: TObject)

var

fld_Id:TIntegerField

fld_Value:TStringField

fld_Time:TDateTimeField

id:Integer

egi

//循环比较最小值

with kbmMemTable1 do

egi

Ope

fld_Id:=TIntegerField(FieldByName('Id'))

fld_Value:=TStringField(FieldByName('Value'))

fld_Time:=TDateTimeField(FieldByName('Time'))

DisableControl

try

First

id := fld_Id.AsInteger

while not Eof do

egi

if id > fld_Id.AsInteger the

id := fld_Id.AsInteger

Next

end

Locate('Id',id,[])

finally

EnableControl

end

end

end

rocere TForm1.Button7Click(Sender: TObject)

egi

//清空

kbmMemTable1.EmptyTable

end

rocere TForm1.FormCreate(Sender: TObject)

egi

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/procts/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/procts/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是我最好的选择。

接下来的博文中,我不再累述教程(没法超越窑主xalion的高度),更侧重资源的分享,容易犯错的地方提醒、原有Bug的勘误,自己开发经验的总结,希望能够有兴趣或有需求的人提供一些帮助。

Delphi的kbmMemTable控件与AdoQuery有什么区别

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

Load Port、SMIF

威孚(苏州)半导体技术有限公司是一家专注生产、研发、销售晶圆传输设备整机模块(EFEM/SORTER)及核心零部件的高科技半导体公司。公司核心团队均拥有多年半导体行业从业经验,其中技术团队成员博士、硕士学历占比80%以上,依托丰富的软件底层...

delphi kbmmw是什么控件

简单点说,kbmMW 与 delphi 自带的 DataSnap 功能类似,是一套用于开发多层应用的框架控件。配合它的kbmMemTable 很容易设计出来多层数据库应用服务器, 所有的功能都在一个包里。同时提供了客户端C,C#,JAVA,PHP 的支持。它支持负载平衡、失效恢复和代理。同时支持 发布/订阅 模式的消息传输方式,大大...

VC++和Delphi那个好用些?那个比较容易学?

1.TkbmMEMTABLE v. 2.33 品质:★★★---评测:一个不错的内存表控件。如果你正急需这方面的控件的话,就试试吧。值得推荐。六Report类 ---说到报表,许多朋友的心里一定会翻涌起种莫名的滋味吧。在品尝过QuickReport带来的尴尬之后,寻找一个优秀的,功能出众的报表控件就一直是我们孜孜以求的,下面为大家推荐两...

如何用内存表处理blob字段

关于内存表的使用说明 一、 Delphi使用内存表 1.1 Delphi创建内存表步骤: 1. 创建一个Ttable实例。 2. 设置一个DataBaseName为一个目录或是已有的数据库别名。 3. 指定TableName的值。 4. 设置TableType属性指明要创建的数据库表类型。(如果此属性为ttDefault表示数据库类型...

绑定控件和非绑定控件的区别 组件插件控件的区别 控件和组件的区别 插件和控件的区别 视图与控件之间的区别 视图和控件的区别 msflexgrid控件 唯一能区别一个控件的属性是 什么是控件
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
...你财富这个金融平台靠谱吗?最近想开始理财了,有没有什么推荐的产品... 如何保持良好的心态,应对生活压力 氟利昂对臭氧层的危害 ...姓党,孩子于2012年12月18日21点21分出生,谢谢!!! 飞利浦录音笔如何使用 大别山到临沂有多远 济南到大别山有动车吗? 大家帮忙一下。我弟弟的作业趣味猜城市名。 ...久雨初睛,雪消冰融,船出长江口,风平浪静,四季花开,海上尽绿洲。_百... 填选城市名(长春.旅顺.宁波.开封.重庆.无锡.贵阳)。 肖万长是哪部电视剧的主角 装机一定要配固态硬盘吗? DIY小白装机求助:哪个牌子的固态硬盘比较耐用和好用? 黎明破晓前电视剧在哪看 关于电脑装机和固态硬盘的问题? 装机时要不要选择固态硬盘? 黎明破晓前电视剧中天使是谁 电脑装机要不要用固态硬盘 装机大佬求推荐!想组建一台游戏电脑,用什么固态硬盘好一点? 我最近在装机,硬盘方面,固态硬盘推荐什么牌子,机械硬盘推荐什么牌子。 电脑固态硬盘怎么装机 欲装机,固态硬盘选什么? 装机装固态硬盘有用吗? 装机固态硬盘选择什么样的好? DIY装机,求推荐固态硬盘! 小孩户口在成都郫县但,住在顺江小区,能在顺江学校上学吗? 关于安置房的分家析产,该如何处理? 为什么我解冻,绑的银行卡号后8位不对? 苏稽廉租房在哪里,2017年多久可以交房 成都市顺江小区属哪个派出所管?我是外地租户,在顺江小区暂住,想办居住证去哪个派出所办理? 天津传媒学院怎么样啊? 天津传媒学院怎么样? 天津传媒学院有什么专业 天津哪些大学有传媒专业? 天津有关于传媒的大学吗??? 天津传媒学院和武汉传媒学院哪个好? 有没有传媒类专业比较好而且综合性较好的大学? 宝宝鸡汤里放什么食材好 儿童鸡汤怎么做 童子鸡汤怎样做的做法 微信上怎么查询购物记录? 金刚菩提子冬天天气太干燥了 裂了怎么办? DNF最强百级史诗单件,歧路鞋可增加第一栏护石技能55%攻击力,如何? dnf100级史诗套排名是怎样的? DNF:100级新增副本中,哪里可以获取100级史诗装备和神话装备? 青铜葵花中,为了让葵花更漂亮地登台主持节目,为她制作了一串用什么做的项链 青铜葵花测试卷答案 《青铜葵花》的我的感受? 青铜葵花5篇超短读书笔记 这个游戏代码 能否请大佬把代码+1改成+500?