Windows XP/Delphi 7中的持久化对象

5
我正在尝试在Delphi 7,Windows XP中制作一个AlarmSystem。我必须在数据库(MS SQL Server 2000)中注册警报。但是如果服务器宕机怎么办?我可以想象我必须持久化TAlarm类型的对象。那么,我该如何做呢?也许继承自TComponent?请问我该如何做?
非常感谢。
很抱歉我的英语不好。
这里有更多信息... TAlarm是从TObject派生的类。还有10个以上的类从TAlarm派生(一些类型的警报)。TAlarm具有一个名为FParams:TParams的字段,子类仅具有Execute方法。字段FParams可以是不同类型:TAlarmX1_Params,TAlarmX2_Params等等。

您需要提供更多信息。TAlarm基于哪种类型?您需要存储什么内容? - Ken White
1
询问更多信息的原因是,如何持久化事物取决于您要保存什么。例如,如果您只需要存储警报的日期和时间以及警报用途的描述,则可以将其保存在INI文件中,而无需存储类的所有其他部分。但是,如果您的需求比这更复杂,最好以某种方式存储整个类。如果没有更多了解,很难为您提供一个好的答案。 - Ken White
抱歉,现在你已经有了我的问题中的新信息。希望这能帮到你。感谢你的帮助。 - DelphiProgrammer
请查看有关存储多个对象的后续问题:http://stackoverflow.com/questions/1673741/persisting-more-than-one-object-in-delphi-7-closed - Rob Kennedy
@MLB,请查看新的示例以持久化多个对象。 - RRUZ
4个回答

4
你可以继承自TPersistent,然后使用TJvAppXMLFileStorage (JVCL) 组件来序列化TAlarm类。
保存对象:
uses
  JvAppXMLStorage;

Procedure SaveMyObject(MyAlarm : TAlarm)
var
  MyStore: TJvAppXMLFileStorage;
begin
  MyStore:= TJvAppXMLFileStorage.Create(nil);
  try
    MyStore.WritePersistent('', MyAlarm);
    MyStore.Xml.SaveToFile('C:\MyAlarm.xml');
  finally
    MyStore.Free;
  end;
end;

恢复一个对象

uses
  JvAppXMLStorage;

Procedure LoadMyObject(MyAlarm : TAlarm)
var
  MyStore: TJvAppXMLFileStorage;
begin
  MyStore:= TJvAppXMLFileStorage.Create(nil);
  try
    MyStore.FileName:='C:\MyAlarm.xml';        
    MyStore.Xml.LoadFromFile('C:\MyAlarm.xml');
    MyStore.ReadPersistent('', MyAlarm);
  finally
    MyStore.Free;
  end;
end;

更新

如果您需要将多个对象持久化到XML文件中,您必须为WritePersistent和ReadPersistent方法分配一个路径(唯一标识符)。

请参考以下示例:

多个持久化

Procedure SaveMyObjects(MyObjects : Array of TComponent);
var
  MyStore: TJvAppXMLFileStorage;
  i      : integer;
begin
  MyStore:= TJvAppXMLFileStorage.Create(nil);
  try
    for i := Low(MyObjects) to High(MyObjects) do
     MyStore.WritePersistent(MyObjects[i].Name, MyObjects[i]); //In this case i use the name property of the component.
    MyStore.Xml.SaveToFile('C:\Tools\MyAlarm.xml');
   finally
    MyStore.Free;
  end;
end;

保存组件

SaveMyObjects([Button1,Button2,Edit1,Edit2]);

多重加载

Procedure LoadMyObjects(MyObjects:Array of TComponent);
var
  MyStore    : TJvAppXMLFileStorage;
  i          : integer;

begin
  MyStore:= TJvAppXMLFileStorage.Create(nil);
  try
    MyStore.FileName:='C:\Tools\MyAlarm.xml';
    MyStore.Xml.LoadFromFile('C:\Tools\MyAlarm.xml');
    for i := Low(MyObjects) to High(MyObjects) do
      MyStore.ReadPersistent(MyObjects[i].Name, MyObjects[i]);
  finally
    MyStore.Free;
  end;
end;

恢复属性
LoadMyObjects([Button1,Button2,Edit1,Edit2]);

加载的另一种选择

Procedure LoadMyObjectById(Id:String;MyObject:TComponent); //using the id of the object
var
  MyStore    : TJvAppXMLFileStorage;
  i          : integer;

begin
  MyStore:= TJvAppXMLFileStorage.Create(nil);
  try
    MyStore.FileName:='C:\Tools\MyAlarm.xml';
    MyStore.Xml.LoadFromFile('C:\Tools\MyAlarm.xml');
   MyStore.ReadPersistent(id, MyObject);
  finally
    MyStore.Free;
  end;
end;

你必须以这种方式运行它。

LoadMyObjectById(Button1.Name,Button1); //Again using the Name property.

我希望这个例子对你有所帮助 ; )

我没有看到任何分配新值给 MyAlarm 参数的代码,那为什么它们要通过引用传递呢? - Rob Kennedy
2
好的,没错...但是如果我需要持久化多个对象怎么办?如何从XML中读取多个对象?? - DelphiProgrammer
你可以使用 tObjectList 来保存多个对象并通过迭代列表进行写入操作。 - skamradt
1
Skamradt,TObjectList不是从TPersistent派生的,因此无法在给定的函数中使用。此外,Yulien似乎尝试使用Rruz的函数保存多个对象,但每个对象都会覆盖先前的对象。请参见后续问题:http://stackoverflow.com/questions/1673741/persisting-more-than-one-object-in-delphi-7-closed - Rob Kennedy

0

您可以将信息保存在本地的XML或INI文件中。这不需要更改TAlarm的继承方式。但是,您需要手动持久化和恢复所有希望在本地持久化的属性。这应该不会太复杂。


抱歉,朋友,但我从未持久化过对象。请告诉我在哪里可以找到有关持久化的教程或手册。我如何将信息持久化地保存在XML或INI文件中?请给个例子。非常感谢。 - DelphiProgrammer

0

如果你要保存数据的服务器宕机了,通常最好的方法是使操作失败并返回错误。这样,你就不需要两个独立的序列化代码,两者必须保持同步,并且一种方式是在服务器恢复后将本地数据上传到服务器。

此外,如果你的应用程序依赖于远程服务器,用户可能无法离线使用它,所以从用户界面的角度来看,这并不是一个坏主意。


0

我曾经使用过本地数据库,通过ADO访问一个Access mdb文件,其架构与服务器相同。当连接恢复时,我进行了同步。但是,现在我已经放弃了这种技术。当连接丢失或服务器关闭时,应用程序将无法运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接