Текущий архив: 2006.11.05;
Скачать: CL | DM;
Внизсериализация своего объекта в базу Найти похожие ветки
← →
Tab (2006-10-18 10:48) [0]Создал свой объект, как сериализовать его в базу? например FB. Буду благодарен за пример.
← →
Desdechado © (2006-10-18 11:06) [1]Если он наследник от TPersistent, то перекрой SaveToStream и сливай все в BLOB-поле.
← →
Сергей М. © (2006-10-18 11:14) [2]
> как сериализовать его в базу?
Записать последовательно свойства объекта в TBlobStream
← →
Tab (2006-10-18 12:42) [3]
> Если он наследник от TPersistent,
нет он
> Записать последовательно свойства объекта в TBlobStream
пожалуйста киньте примером
← →
Сергей М. © (2006-10-18 12:45) [4]http://www.google.ru/search?q=%D0%94%D0%B5%D0%BB%D1%84%D0%B8+%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5+%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0+%D0%B2+%D0%BF%D0%BE%D1%82%D0%BE%D0%BA&start=0&ie=utf-8&oe=utf-8&client=firefox-a&rls=org.mozilla:ru:official
← →
StriderMan © (2006-10-18 13:35) [5]
procedure TKLCForm.SaveToBlob(const AField: TBlobField);
var
bs: TStream;
begin
bs := AField.DataSet.CreateBlobStream(AField, bmWrite);
try
bs.WriteDescendent(Self, nil);
finally
bs.Free;
end;
end;
писалось давно, поэтому пояснить почемуWriteDescendent
не смогу. Но работает именно на FB/IBX.
← →
Tab (2006-10-18 14:00) [6]а если это не компонент а объект типа
type
Figure_= class
objType: integer;
pt_l: array [1..2] of TGPPoint;
first_p_set: boolean;
procedure Draw(gp: TGPGraphics); virtual; abstract;
end;
← →
Сергей М. © (2006-10-18 14:04) [7]
> если это не компонент а объект типа
значит следует последовательно записать в стрим значния тех св-в объекта, которые уникально идентифицируют этот объект.
← →
Tab (2006-10-18 15:26) [8]чтение в просто обратном порядке7
← →
Сергей М. © (2006-10-18 15:30) [9]
> Tab (18.10.06 15:26) [8]
Чтение в том же порядке
← →
StriderMan © (2006-10-18 15:55) [10]
> Tab (18.10.06 14:00) [6]
> а если это не компонент а объект типа
> type
> Figure_= class
а в чем проблема унаследоваться от TComponent?
← →
Сергей М. © (2006-10-18 16:01) [11]
> в чем проблема унаследоваться от TComponent?
Распространенное заблуждение - "мой наследник класса TComponent занимает слишком дофига места в какой-то там памяти, сам не знаю в какой, но друган мой типа сказал что так"
← →
StriderMan © (2006-10-18 18:04) [12]
> Сергей М. © (18.10.06 16:01) [11]
TComponent как раз тот самый велосипед, который такие "друганы" упорно изобретают: у кого колесо квадратное, у кого педалей нет, у кого "седло от унитаза, а педаль от пианино", а руль от КАМАЗа
← →
Tab (2006-10-18 20:14) [13]
> а в чем проблема унаследоваться от TComponent?
что мне это даст ?
удобоство при обработке SaveToStream?
Просто в программе счет будет идти на сотни
← →
StriderMan © (2006-10-19 11:34) [14]
> Tab (18.10.06 20:14) [13]
>
> > а в чем проблема унаследоваться от TComponent?
>
> что мне это даст ?
> удобоство при обработке SaveToStream?
> Просто в программе счет будет идти на сотни
и в этих сотнях компонент в каждом описывать сохранение свойств??
в наследниках TComponent достаточно их поместить в секцию published и он все сделает за тебя
← →
Сергей М. © (2006-10-19 11:51) [15]
> Tab (18.10.06 20:14) [13]
> что мне это даст ?
Это (см. [14]) даст универсальность и возможность использования готовой технологии Delphi streaming system, как раз и разработанной Борландом для упрощения и унификации сохранения/воспроизведения объектов.
← →
Tab (2006-10-19 13:24) [16]procedure MLine.SaveToStream(const AField: TBlobField);
var
bs: TStream;
begin
bs := AField.DataSet.CreateBlobStream(AField, bmWrite);
try
bs.WriteDescendent(Self, nil);
finally
bs.Free;
end;
end;
в программе делаю так:
Dm.IBTable1.Edit;
Layer[1].SaveToStream(dm.IBTable1DATA_B);
данные вроде сохранились. так правильно?
а обратную операцию чето не понял как?
Через Query? Выбрать записи, затем в цикле прочитать из BLOB ReadFromStream?
Если так то ругается то MLine неподходит для TComponent
procedure MLine.LoadFromStream(const AField: TBlobField);
var
bs: TStream;
begin
bs := AField.DataSet.CreateBlobStream(AField, bmWrite);
try
self:=bs.ReadComponent(nil);
finally
bs.Free;
end;
end;
← →
Сергей М. © (2006-10-19 14:38) [17]
> обратную операцию чето не понял как?
Ну куда уж тут понятней ...
Если "запись" - это "SaveToЧтоТоТам", то "чтение" = "LoadFromЧтоТоТам" ...
← →
Tab (2006-10-19 14:54) [18]
> Ну куда уж тут понятней ...Если "запись" - это "SaveToЧтоТоТам",
> то "чтение" = "LoadFromЧтоТоТам" ...
ну приведеный выше мной код для чтенеия не работает. В BLOB записались данные название класса, и еще какие-то нечитаемые.
← →
Игорь Шевченко © (2006-10-19 14:57) [19]Успешно использую SaveToBlob, LoadFromBlob в течение нескольких лет.
Теперь придется выкидывать, а жалко...
← →
Сергей М. © (2006-10-19 15:00) [20]
> Tab (19.10.06 14:54) [18]
> приведеный выше мной код для чтенеия не работает
Ошибка за пределами этого кода не исключена.
> какие-то нечитаемые.
Значит лупа не той системы
← →
Tab (2006-10-19 15:10) [21]
> Успешно использую SaveToBlob, LoadFromBlob в течение нескольких
> лет.Теперь придется выкидывать, а жалко...
да нет, зачем же выкидывать. Лучше поделитесь своим успешным опытом использования, дав пару примеров. Буду очень благодарен.
> Ошибка за пределами этого кода не исключена.
кажется одну нашел:
procedure MLine.LoadFromStream(const AField: TBlobField);
var
bs: TStream;
begin
bs := AField.DataSet.CreateBlobStream(AField, bmRead ? );
try
self:=bs.ReadComponent(nil);
finally
bs.Free;
end;
end
← →
Tab (2006-10-19 15:21) [22]т.е. снначала надо из blob в Stream а как потом из Stream прочесть данные их класса?
procedure MLine.LoadFromStream(const AField: TBlobField);
var
bs: TStream;
begin
bs := AField.DataSet.CreateBlobStream(AField, bmRead);
try
TComponent(self):=bs.ReadComponent(nil);
finally
bs.Free;
end;
end;
на выделенной строчке ругается class MLine not found
← →
StriderMan © (2006-10-19 15:27) [23]
> Tab (19.10.06 13:24) [16]
> procedure MLine.LoadFromStream(const AField: TBlobField);
> var
> bs: TStream;
> begin
> bs := AField.DataSet.CreateBlobStream(AField, bmRead);
> try
> bs.ReadComponent(Self);
> finally
> bs.Free;
> end;
> end;
← →
Tab (2006-10-19 15:46) [24]проверил на Integer и String
а вот типы TGPPen, TGPPoint не читает пишет по нулям.
почему может быть?
type
MFigure_= class (TComponent)
public
MPen : TGPPen;
objType: integer;
pt_l: array [1..2] of TGPPoint;
end;
← →
Tab (2006-10-19 15:52) [25]Может запись не правильно:
procedure MLine.SaveToStream(const AField: TBlobField);
var
bs: TStream;
begin
bs := AField.DataSet.CreateBlobStream(AField, bmWrite);
try
bs.WriteDescendent(Self, nil);
finally
bs.Free;
end;
end;
← →
StriderMan © (2006-10-19 16:21) [26]
> Tab (19.10.06 15:46) [24]
автоматом только простые типы сохраняются ну и другие компоненты.
сложные типы надо научить сохранять
для этого есть метод.procedure DefineProperties(Filer: TFiler); override;
там надо написать что-то типаinherited DefineProperties(Filer);
Filer.DefineProperty("RecParts", ReadRecParts, WriteRecParts, True);
//жирные - ссылки на методы чтения/записи
procedure TKLCReceiptForm.ReadRecParts(Reader: TReader);
var
i: TReceiptPart;
begin
i := TReceiptPart(0);
Reader.ReadListBegin;
while not Reader.EndOfList do
begin
fRecParts[i] := Reader.ReadFloat;
if i > high(fRecParts) then break;
inc(i);
end;
Reader.ReadListEnd;
end;
← →
Игорь Шевченко © (2006-10-19 17:12) [27]Tab (19.10.06 15:10) [21]
> да нет, зачем же выкидывать. Лучше поделитесь своим успешным
> опытом использования, дав пару примеров. Буду очень благодарен.
>
Выкидывать затем, что это неправильный способ работы с данными в базе.
Писать примеры долго, промышленный код я не дам, но общая схема проста:
Сохраняемый объект наследуется от TComponent, у него переписывается метод DefineProperties, если класс содержит что-то кроме элементарных типов.
Класс обязательно регистрируется (RegisterClass)
Код сохранения схематично выглядит так:
procedure SaveFoo(Foo: TFoo; KeyID: Integer);
begin
var
MS: TMemoryStream;
begin
MS := TMemoryStream.Create;
try
MS.WriteComponent(Foo);
qryFooUpd.ParamByName("KEYID").AsInteger := KeyID;
qryFooUpd.ParamByName("AnObject").LoadFromStream(MS, ftBlob);
qryFooUpd.ExecSQL;
finally
MS.Free;
end;
end;
Код загрузки схематично выглядит так:
function LoadFoo (ABlob: TBlobField): TFoo;
begin
Result := TFoo.Create(nil);
if not Result.Load(ABlob) then
FreeAndNil(Result);
end;
function TFoo.Load(ABlob: TBlobField): Boolean;
var
MS: TMemoryStream;
begin
Result := not ABlob.IsNull;
if Result then begin
Clear;
MS := TMemoryStream.Create;
try
ABlob.SaveToStream(MS);
MS.Position := 0;
MS.ReadComponent(Self);
finally
MS.Free;
end;
end;
end;
← →
Tab (2006-10-19 20:37) [28]Решил попробовать сначала на числах и строках. Сделал аналог SaveFoo, но в Blob строки или числа не записываются.
← →
Сергей М. © (2006-10-20 10:28) [29]
> в Blob строки или числа не записываются
Значит у тебя ошибка в программе.
← →
Slym © (2006-10-20 10:54) [30]type
MFigure_= class (TComponent)
published?
MPen : TGPPen;
objType: integer;
pt_l: array [1..2] of TGPPoint;
end;
← →
Tab (2006-10-20 13:48) [31]после указания
published
не принимает типы Integer проч. как их тогда добавить в класс.
← →
StriderMan © (2006-10-20 13:57) [32]
> type
> MFigure_= class (TComponent)
private
fMPen: TGPen;
> published?
> property MPen : TGPPen read fMPen write fMPen;
> property objType: integer read .. write...;
> property pt_l: array [1..2] of TGPPoint read .. write ..;
> end;
← →
Ученик чародея © (2006-10-20 16:12) [33]Чистый класс при создании от TObject занимает 8 байт памяти, чистый класс наследованный от TComponent занимает 48 байт памяти.
type TMyClass=class(TComponent)
end;
var
Form1: TForm1;
var MC:array of TMyClass;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
begin
Form1.Caption:="Old="+IntToStr(AllocMemSize);
//SetLength(MC,cArrLen);
for i:=0 to (cArrLen-1) do
MC[i]:=TMyClass.Create(nil);
//
Form1.Caption:=Form1.Caption+"Now="+IntToStr(AllocMemSize);
end;
← →
Ученик чародея. (2006-10-20 16:14) [34]Ну тоесть объект этого класса.
А если у меня этих объектов более 10^7 то выигрыш налицо.
← →
Игорь Шевченко © (2006-10-20 16:50) [35]Ученик чародея © (20.10.06 16:12) [33]
> Чистый класс при создании от TObject занимает 8 байт памяти,
> чистый класс наследованный от TComponent занимает 48 байт
> памяти.
И какое отношение это имеет к теме ветки ?
← →
Ученик чародея © (2006-10-20 16:56) [36]
> Игорь Шевченко © (20.10.06 16:50) [35]
>
> Ученик чародея © (20.10.06 16:12) [33]
>
>
> > Чистый класс при создании от TObject занимает 8 байт памяти,
>
> > чистый класс наследованный от TComponent занимает 48
> байт
> > памяти.
>
>
> И какое отношение это имеет к теме ветки ?
[11],[12]
Страницы: 1 вся ветка
Текущий архив: 2006.11.05;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.159 c