我的代码有什么问题?我尝试保存,然后再次将对象加载到数据库中的blob字段,但什么也得不回来。
记录已保存,但我无法说明数据是否写得正确,因为我无法读回数据。
这是对象类型:
TMyObject = class
Name: string;
end;
在这里我试着保存:
procedure TForm1.btnSaveObjectClick(Sender: TObject);
var
myObject: TmyObject;
aMemoryStream: TMemoryStream;
begin
myObject:= TMyObject.Create;
myObject.Name:=edtName.Text;
aMemoryStream:= TMemoryStream.Create;
aMemoryStream.Write(myObject, myObject.InstanceSize);
aMemoryStream.Position:=0;
with TSQLQuery.Create(nil) do
begin
DataBase:=Conn;
SQL.Text:='INSERT INTO testtable (data) VALUES (:data)';
try
ParamByName('data').LoadFromStream(aMemoryStream, ftBlob);
ExecSQL;
TX.CommitRetaining;
finally
aMemoryStream.Free;
myObject.Free;
Free;
end;
end;
end;
尝试再次备份数据:
procedure TForm1.btnLoadObjectClick(Sender: TObject);
var
myObject: TMyObject;
BlobStream : TStream;
begin
with TSQLQuery.Create(nil) do
begin
DataBase:=Conn;
SQL.Text:='SELECT data FROM testtable';
myObject:= TmyObject.Create;
try
Open;
Last;
BlobStream:= CreateBlobStream(FieldByName('data'), bmread);
BlobStream.Position:=0;
BlobStream.Read(myObject, BlobStream.Size);
ShowMessage('Stored Name: ' +myObject.Name);
finally
myObject.Free;
Free;
end;
end;
end;
另外,BlobStream应该是免费的吗?
答案 0 :(得分:3)
将对象存储到文件,流或blob字段的正确方法是首先使用其他方法扩展对象,以便将对象字段(对象内部变量)中的数据加载和保存到单个内存块中。
您可以通过一个接一个地保存一个字段来完成此操作。
如果您的对象是动态调整大小(包含动态数组或字符串),请不要忘记分别存储这些对象的大小,这样您以后在加载对象时就会知道有多少数据属于它们。
此外,如果您的对象包含其他一些对象,您还需要它们具有类似的方法来存储和加载它们的数据。
实施在很大程度上取决于您对象的课堂设计。这是字符串字段的代码示例:
type
TMyObject = class
public
Name: string;
procedure SaveToStream(AStream: TStream);
procedure LoadFromStream(AStream: TStream);
end;
procedure TMyObject.SaveToStream(AStream: TStream);
var
Len: Integer;
begin
Len := Length(Name);
AStream.Write(Len, SizeOf(Len));
AStream.Write(PChar(Name)^, Len);
end;
procedure TMyObject.LoadFromStream(AStream: TStream);
var
Len: Integer;
begin
AStream.Read(Len, SizeOf(Len));
SetString(Name, PChar(nil), Len);
AStream.Read(PChar(Name)^, Len);
end;
有了这个,就可以使用CreateBlobStream返回的流,只需将myObject保存到blobfield:
BlobField := FieldByName('data') as TBlobField;
Stream := CreateBlobStream(BlobField, bmWrite);
myObject.SaveToStream(Stream);
..或从流中加载:
Stream:= CreateBlobStream(FieldByName('data'), bmread);
myObject.LoadFromStream(Stream);