Welcome

首页 / 软件开发 / Delphi / 第二十章-开发Delphi对象式数据管理功能(五)(5)

第二十章-开发Delphi对象式数据管理功能(五)(5)2007-05-0720.3.2 数据库BLOB字段应用

Delphi VCL提供了TBlobStream对象支持对数据库BLOB字段的存取。Delphi 的TBlobStream对象的作用在于一方面可以使Delphi应用程序充分利用多媒体数据库的数据管理能力。另一方面又能利用Delphi Object Pascal的程序设计能力给关系型多媒体数据库提供底层控制能力和全方位的功能扩展余地。

20.3.2.1 TBlobStream的使用

TBlobStream对象用一个TBlobField类型的对象作为参数来创建与BLOB字段相联的BLOB流,接着就可用流的存取方法在BLOB字段中存取数据。

var

BlobStream: TBlobStream;

I: Integer;

begin

BlobStream := TBlobStream.Create(TBlobField(CardTable.Fields[10], bmWrite);

With TWriter.Create(BlobStream, 4096) do

try

for I := 0 to DesignWin.ControlCount - 1 do

begin

WriteInteger(MMID[i]);

WriteRootComponent(DesignWin.Controls[i]);

{ 写相应媒体扩展信息 }

……

end;

WriteListEnd;

finally.

Free;

end;

BlobStream.Free;

CardTable.Post;

end;

Fields变量是表示数据库记录的字段数组,Fields[10]正是数据库的BLOB 字段。CardTable的Post方法将数据库的修改反馈到数据库的物理存储上。

上面这段程序是超媒体卡片存储的部分源程序,我们就是将卡片保存在数据库BLOB字段中,实现将超文本和关系数据库两种数据管理方式结合起来。读卡片的程序如下:

var

PropInfo: PPropInfo;

Method: TMethod;

Blobtream: TStream;

I: Integer;

begin

BlobStream := TBlobStream.Create(TBlobField(CardTable.Fields[10]), bmRead);

With TReader.Create(BlobStream, 4096) do

try

while not EndOfList do

begin

case ReadInteger of

IDText: begin

Ctrl := TControl(ReadRootComponent(nil));

PropInfo := GetPropInfo(Ctrl.ClassInfo, "OnClick");

Method.Code:= Self.MethodAddress(MethodName);

Method.Data := Self;

if Method.Code <> nil then

SetMethodProp(Ctrl, PropInfo, Method);

DesignWin.InsertControl(Ctrl);

end;

IDImage:

……

end;

……

WriteListEnd;

end;

finally.

Free;

end;

FileStream.Free;

end;

20.3.2.2 BLOB字段与图形图像

在多媒体数据库中处理得比较多的是图形图像,因此早期的多媒体数据库在扩展关系数据库时往往是增加一个图像字段。BLOB字段是以二进制数据存储方式,因此它完全可以表达图形图像数据。

在TBlobField对象中提供了LoadFromBitMap和SaveToBitMap方法存取位图数据。它们在实现上都是使用BlobStream对象。

procedure TBlobField.LoadFromBitmap(Bitmap: TBitmap);

var

BlobStream: TBlobStream;

Header: TGraphicHeader;

begin

BlobStream := TBlobStream.Create(Self, bmWrite);

try

if (DataType = ftGraphic) or (DataType = ftTypedBinary) then

begin

Header.Count := 1;

Header.HType := $0100;

Header.Size := 0;

BlobStream.Write(Header, SizeOf(Header));

Bitmap.SaveToStream(BlobStream);

Header.Size := BlobStream.Position - SizeOf(Header);

BlobStream.Position := 0;

BlobStream.Write(Header, SizeOf(Header));

end else

Bitmap.SaveToStream(BlobStream);

finally

BlobStream.Free;

end;

end;

procedure TBlobField.SaveToBitmap(Bitmap: TBitmap);

var

BlobStream: TBlobStream;

Size: Longint;

Header: TGraphicHeader;

begin

BlobStream := TBlobStream.Create(Self, bmRead);

try

Size := BlobStream.Size;

if Size >= SizeOf(TGraphicHeader) then

begin

BlobStream.Read(Header, SizeOf(Header));

if (Header.Count <> 1) or (Header.HType <> $0100) or

(Header.Size <> Size - SizeOf(Header)) then

BlobStream.Position := 0;

end;

Bitmap.LoadFromStream(BlobStream);

finally

BlobStream.Free;

end;

end;

程序中按两种方式存取数据,对于位图数据,数据的起点是流的Potition为0处,对于图形或其它类型的Blob数据,则以流的Position为SizeOf(Header) + 1处开始, 即多了个头信息。

20.3.2.3 BLOB字段与文本

Delphi BLOB字段中增加了大型文本的处理能力。可以在TBlobField和Strings中自由地交换数据。

procedure TBlobField.LoadFromStrings(Strings: TStrings);

var

BlobStream: TBlobStream;

begin

BlobStream := TBlobStream.Create(Self, bmWrite);

try

Strings.SaveToStream(BlobStream);

finally

BlobStream.Free;

end;

end;

procedure TBlobField.SaveToStrings(Strings: TStrings);

var

BlobStream: TBlobStream;

begin

BlobStream := TBlobStream.Create(Self, bmRead);

try

Strings.LoadFromStream(BlobStream);

finally

BlobStream.Free;

end;

end;