Delphi - 使用不同的TTable和TQuery作为一个对象

Posted

技术标签:

【中文标题】Delphi - 使用不同的TTable和TQuery作为一个对象【英文标题】:Delphi - Using different TTable and TQuery as one object 【发布时间】:2011-12-29 03:11:40 【问题描述】:

德尔福 2010,Win7 - 64

我正在编写一个涉及连接到不同数据库的应用程序。我使用两个不同的供应商进行数据库访问。我使用 DA-Soft 的 AnyDAC,它允许我连接到“工业”数据库、Oracle、SQL Server 等,我使用 ComponentAce 的 ABS 数据库,这是一个基于 PC 的小型 SQL 数据库。 (顺便说一句,我强烈推荐)。我的问题是我需要编写一系列可以针对任一供应商组件的通用例程。

这两个组件都有 TTable 和 TQuery 组件。我需要编写一套例程,其中一些是基于TTable的,一些是基于TQuery的。这些例程可以针对任一供应商组件。

例如,我需要能够遍历 TTable 中的所有行。第一次运行例程时,我需要它使用 DA-Soft 的 TTable。下次我运行它时,我需要它针对 Component Ace 的 TTable 运行它。 TQuery 也存在同样的情况。

我在这里需要一个抽象层——至少我认为我需要。我不想多次编写每个例程。推荐什么来提供这一层抽象/间接。我并不过分担心令人眼花缭乱的速度。请记住 - 越简单越好,而且我不是专业程序员....

任何想法表示赞赏。 谢谢大家。

【问题讨论】:

你能把 TTable 和 TQuery 作为它们共同的祖先 TDataSet 传递吗? 【参考方案1】:

我假设他们都是 TDataSet 的后代。

在最简单的情况下,您可以编写您只需要一个 TDataSet 参数的例程。您可以访问 TDataSet.Next 和 FieldByName。这将涵盖相当多的情况。

如果您的例程需要为每种 TDataSet 类型调用不同的代码,那么您最好的选择是使用接口并创建每种类型的自定义后代

IMyDataSetOperations = interface 
  procedure OpenSpecial;
  function GetDataSet: TDataSet;
end;

TMyAnyDacTable = class(TAnyDacTable, IMyDataSetOperations)
  procedure OpenSpecial;
  function GetDataSet: TDataSet;
end;

TMyComponentAceTable = class(TComponentAceTable, IMyDataSetOperations)
  procedure OpenSpecial;
  function GetDataSet: TDataSet;
end;

procedure TMyAnyDacTable.OpenSpecial
begin
  // code specific for AnyDAC dataset
end;

function TMyAnyDacTable.GetDataSet: TDataSet;
begin
  result := self;
end;

然后你可以只使用 IMyDataSetOperations 接口来编写你的例程

function CalculateAverage(const AMyDataSet: IMyDataSetOperations): Currency;
var
  total: Currency;
  i: Count;
begin
  AMyDataSet.OpenSpecial;
  i := 0;
  total := 0;
  AMyDataSet.GetDataSet.First;
  while not AMyDataSet.GetDataSet.Eof do
  begin
    total := total + AMyDataSet.GetDataSet.FieldByName('Amount').AsCurrency;
    Inc(i);  
    AMyDataSet.GetDataSet.Next;
  end

  if i > 0 then
    result := total / i
  else
    result := 0;
end

【讨论】:

【参考方案2】:

我建议你使用对象持久性框架。我认为 Instant Object 是很好的 OPF。现在我正在使用它。通过使用 OPF,我们的应用程序将独立于 DBMS,我们无需为每个例程多次创建例程。

【讨论】:

在某种程度上,AnyDAC 控件是一种对象持久性框架。它们支持大约 15 种不同的数据库引擎,但不是真正的本地数据库引擎,即 SQL 访问,但不必安装 LOCAL 数据库引擎,这就是我使用 Component Ace 的 ABS 数据库的原因。 AnyDAC 也支持本地数据库:SQLite、Advantage Database (dbf)、MS Access

以上是关于Delphi - 使用不同的TTable和TQuery作为一个对象的主要内容,如果未能解决你的问题,请参考以下文章

即使数据库表存在,Delphi TTable.Exists 在 Paradox 表上也会失败

delphi中用Table表组件和Query查询组件配合进行的增删改查

delphi dataset DisableControls

Delphi实现在数据库中存取图像

如何将adoquery中的数据复制到 Ttable 中

Delphi查询优化