QDB 使用 QDataSet 实现主从表的效果

swish

Moderater
Staff member
Moderater
#1
转载自QDAC官网网站,文章发现问题可能随时更新,最新版本请访问:
You do not have permission to view link Log in or register now.


QDataSet 做为 QDB 的重要组成部分,目前已经支持主从表的设定。QDataSet 的主从表支持与一般的数据集略有不同,我做了一些简化和增强处理。设定主从表第一步与一般的数据集没有什么不同,设置从表的 MasterSource 为主表的数据源( DataSource ),但接下来就有所不同了:
1、直接通过设置 MasterFields 来激活主从关系
MasterFields 的格式进行了增强,不再是分别设置 MasterFields 和 IndexFields 。直接设定关键字段关联即可,格式为:
主表字段=从表字段[;主表字段=从表字段]...
如果主表字段和从表字段名一样,可以只写主表字段,多个字段间通过分号或逗号直接分隔即可,示例如下:
Code:
FDetailDataSet.MasterSource := DataSource1;
FDetailDataSet.MasterFields := 'id=MasterId';
2、通过 OnMasterChanged 事件来获取从表数据
有时候,我们并不想一次性获取到所有的从表数据,那么,我们在设置为从表的 MasterSource 后,就可以设置 OnMasterChanged 事件的响应程序来自行编写脚本来获取明细数据,如:
Code:
rocedure TForm1.DoMasterChanged(ADataSet: TDataSet);
begin
  FProv.OpenDataSet(FDetailDataSet, 'select * from pg_attribute where attrelid='
    + FMasterDataSet.FieldByName('oid').AsString);
end;
Hjz8BzUF8J2lsHfArX7hCHfDBu77nFrB.gif
 
Last edited by a moderator:

swish

Moderater
Staff member
Moderater
#3
好了,方法2虽然每次只取部分明细记录,但问题是当我们重复浏览记录时,还会需要重复查询。这显然与我们减少网络数据传输的思路是背道而驰的,所以,我们可以进一步优化:
Code:
procedure TForm1.DoMasterChanged(ADataSet: TDataSet);
var
  S: QStringW;
  ASub: TQDataSet;
  I: Integer;
begin
  try
    Inc(FRequests);
    S := 'select * from pg_attribute where attrelid=' +
      FMasterDataSet.FieldByName('oid').AsString;
    for I := 0 to FDetailDataSet.RecordsetCount - 1 do
    begin
      if FDetailDataSet.Recordsets[I].CommandText = S then
      begin
        FDetailDataSet.ActiveRecordset := I;
        Inc(FHits);
        Exit;
      end;
    end;
    ASub := FProv.OpenDataSet(S);
    FDetailDataSet.AddDataSet(ASub);
    FDetailDataSet.ActiveRecordset := FDetailDataSet.RecordsetCount - 1;
  finally
    Panel2.Caption := '总计: ' + IntToStr(FRequests) + ' 次请求,缓存命中:' +
      IntToStr(FHits) + '次';
  end;
end;[/I]

这里我加入了一个统计来计算减少查询的次数,看效果吧:

You do not have permission to view link Log in or register now.
 
Last edited by a moderator:

swish

Moderater
Staff member
Moderater
#4
针对上面的情况,群里有朋友问,这样缓存的话,数据库里数据万一更新了怎么办?
实际上很好办呀,你如果知道更新了,将对应的缓存项目用OpenDataSet重新打开下就好了。这块点代码相信就不用我写了,至于如何数据发生了变更,那就不是 QDB 所要关心的内容了,需要你自己去实现,比如象网页一样,设置一个过期时间,过期后的缓存项目重取,都是一个办法(虽不是最佳)。