遍历dataset

来源:互联网 发布:乐乎lofter南山兵哥 编辑:程序博客网 时间:2024/05/21 19:22

      如何遍历Dataset

遍历一个Dataset中的数据主要有以下两种方式:

l         方法一

datasetX.moveFirst();

while (!datasetX.isLast()) {

      ... ... ...

      datasetX.moveNext();

}

l         方法二

var record = datasetX.getFirstRecord();

while (record != null) {

       ... ... ...

       record = record.getNextRecord();

}

如无特殊需要,我们推荐使用第二种方法完成对Dataset的遍历。这两种遍历方式的区别在于,第一种遍历方式是通过不断的改变Dataset的当前记录来完成遍历操作的,而第二种遍历方式在遍历的过程中并不会改变Dataset的当前记录。如果此时有任何数据敏感控件绑定在Dataset上,那么,改变Dataset的当前记录将会引起数据敏感控件的刷新动作。如果Dataset中有n条记录,在默认情况下,以第一种方式进行遍历将至少引起相关的数据敏感控件刷新n次,并且当遍历操作结束之后Dataset的当前记录应该总是最后一条记录。

另外,如果被遍历的Dataset是主从绑定关系中的主Dataset。那么直接使用第一种遍历方式将会更加危险,其下的从Dataset可能会随着主Dataset当前记录的改变不断的执行数据加载的动作。数据加载是一种比控件刷新更加耗时的操作。

很多时候,我们使用Dataset遍历是为了修改其中的每一条记录。在这种情况下,如果仅仅是使用此处第二种遍历方式,还远没有达到效率最佳化的目标。此时一定要结合3.4.4中介绍的disableControls()enableControls()才能得到更好的运行效果。

实测数据:

以两种方式对一个包含2000条记录的Dataset进行遍历。实测环境的CPUINTER Pentium(R) 1.73G

l         方法一的耗时为0.256秒。(在进行此方法的测试时我们使用了3.4.4中介绍的disableControls()enableControls()关闭了数据控件的刷新功能,否则速度将慢得无法忍受)

l         方法二的耗时为0.047秒。

由此可见,两种方式间有接近一个数量级的性能差异。方法二的优势非常明显。

      disableControls()enableControls()

DatasetdisableControls()方法和enableControls()方法大概是Dorado开发中最常用的优化技巧了。这个方法非常容易使用,而获取的效果也非常显著,他常常可以将一段代码的执行速度提高好几倍甚至更多。

disableControls()表示暂时禁用Dataset的绑定关系,即暂时禁止Dataset向绑定的数据敏感控件发送任何消息,这样数据敏感控件就不会随着Dataset的变化而自动刷新的。enableControls()则正好相反,表示重新允许Dataset向绑定的数据敏感控件发送消息。

disableControls()enableControls()往往会跟Dataset.refreshControls()方法一起配置使用。refreshControls()的作用是通知所有与改Dataset绑定的数据敏感控件立即进行数据刷新。

假设我们现在要编写一段代码将Dataset中每一条记录的status字段的值设置为completed。未经优化的代码可能是这样的:

var record = datasetX.getFirstRecord();

while (record != null) {

       record.setValue("status", "completed");

       record = record.getNextRecord();

}

假设DatasetX中有n条记录,那么,进行一次这样的遍历将导致相关的数据敏感控件被刷新n次。其实这n次刷新中的前n-1次都是没有任何意义的。

利用disableControls()enableControls()结合refreshControls()优化之后的代码可能是这样的:

datasetX.disableControls();

try {

      var record = datasetX.getFirstRecord();

      while (record != null) {

            record.setValue("status", "completed");

            record = record.getNextRecord();

      }

}

finally {

      datasetX.enableControls();

      datasetX.refreshControls();

}

这样在执行循环的过程中数据敏感控件完全不会刷新,直到循环结束之后,手工调用refreshControls()通知数据敏感控件进行数据刷新。整个操作将需要进行这一次刷新。

disableControls()enableControls()并不总是用在循环操作中,只要是针对Dataset的批量操作都考虑使用这种优化技巧。例如下面的这段用于数据复制的未优化代码:

dataset1.setValue("id", "0001");

dataset1.setValue("name", dataset2.getValue("cname"));

dataset1.setValue("sex", (dataset2.getValue("sex"))?"M":"F");

dataset1.setValue("addr", dataset2.getValue("address"));

dataset1.setValue("tel", dataset2.getValue("telephone"));

dataset1.setValue("email", dataset2.getValue("email"));

dataset1.setValue("web", dataset2.getValue("web"));

dataset1.setValue("cmnt", dataset2.getValue("comment"));

我们同样可以使用disableControls()enableControls()对其进行优化,优化后的代码可能如下:

datasetX.disableControls();

try {

      dataset1.setValue("id", "0001");

      dataset1.setValue("name", dataset2.getValue("cname"));

      dataset1.setValue("sex", (dataset2.getValue("sex"))?"M":"F");

      dataset1.setValue("addr", dataset2.getValue("address"));

      dataset1.setValue("tel", dataset2.getValue("telephone"));

      dataset1.setValue("email", dataset2.getValue("email"));

      dataset1.setValue("web", dataset2.getValue("web"));

      dataset1.setValue("cmnt", dataset2.getValue("comment"));

}

finally {

      datasetX.enableControls();

      datasetX.refreshControls();

}

使用disableControls()enableControls()时还应该注意这样一个细节,这两个方法的运行机制类似于计数器,而不是通常理解的开关。如果对一个Dataset连续执行两次disableControls()方法,那么也必须再执行两次enableControls()才能重新启用绑定关系,即回复Dataset向数据敏感控件发送消息。

下面的代码可能有助于您理解disableControls()enableControls()的运行机制:

// 此时绑定可用

datasetX.disableControls();

// 此时绑定被禁用

datasetX.disableControls();

try {

      // 此时绑定被禁用

}

finally {

      datasetX.enableControls();

      // 此时绑定被禁用

      datasetX.enableControls();

      // 此时绑定可用

}

实测数据:

对一个包含50条记录的Dataset进行遍历,并在遍历的过程中修改每一条记录中的5个字段值。

实测环境的CPUINTER Pentium(R) 1.73G。需要注意的是,此处的测试结果与界面的复杂度密切相关,测试的主要目的是确认未优化代码与优化代码间的性能差异。越是复杂的界面其差异越明显,所以具体的时间值本身参考价值并不大。

l         未经优化的测试代码,其耗时为2.016秒。

var record=dataset1.getFirstRecord();

while (record!=null) {

  record.setValue("field1", "123");

  record.setValue("field2", "234");

  record.setValue("field3", "345");

  record.setValue("field4", "456");

  record.setValue("field5", "567");

  record.post();

  record=record.getNextRecord();

}

l         优化后的测试代码,其耗时为0.25秒。

dataset1.disableControls();

try {

      var record=dataset1.getFirstRecord();

      while (record!=null) {

        record.setValue("field1", "123");

        record.setValue("field2", "234");

        record.setValue("field3", "345");

        record.setValue("field4", "456");

        record.setValue("field5", "567");

        record.post();

        record=record.getNextRecord();

      }

}

finally {

      dataset1.enableControls();

      dataset1.refreshControls();

}

原创粉丝点击