Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.56 MB
Время: 0.033 c
2-1161268969
LBP
2006-10-19 18:42
2006.11.05
DBGRID и удаленные записи


15-1161242512
Серьезный Сэм
2006-10-19 11:21
2006.11.05
Общий доступ


3-1157625300
tytus
2006-09-07 14:35
2006.11.05
Как получить привилегии поьзователя (допустим на SELECT).


15-1160984910
Shorokhov
2006-10-16 11:48
2006.11.05
Оцените задачку


4-1150793137
Lagrima_JN
2006-06-20 12:45
2006.11.05
Приостановка завершения Windows