Dorado 5 : 4.1.Dataset (RF1)

dataset在dorado开发中占有非常重要的地位,是dorado中的核心概念。
dataset类似于MVC架构中的M,用来管理一组二维数据,其结构类似于关系型数据库中的表或视图。
在标准的dorado开发模式当中,dataset的功能基本涵盖了对数据逻辑处理的各项要求。开发人员可以利用dataset来完成绝大部分的数据持久化、数据提取的操作。
另外一点比较重要的是在客户端与服务器端交互的过程中,dorado默认传递的都是dataset对象而不是form元素,因此用dorado开发系统时,我们通常会建议开发人员将页面上的数据尽量组织成为dataset。加以定义和赋值。相关的逻辑也尽量定义在dataset上。
最终客户端与服务器端交互的都是dataset对象,这样可以方便我们可以通过一个比较统一的接口和统一的编码规范实现客户端与服务器端的交互。

原理一:dataset的结构

类似于数据库中的二维表:

图表 7

原理二:当前记录

dataset在有数据的情况下,会拥有当前记录的概念:
记录行指示器,其中三角星图标所在位置即为dataset的当前记录
图表 8
通常情况下我们获取记录的值都是通过如下代码:

var deptId = record.getValue("dept_id");

可是如果要获取当前记录dept_id的值,则可以通过如下的代码:

var record = dataset.getCurrent();
var deptId = record.getValue("dept_id");

甚至dataset的api允许我们简写为:

var deptId = dataset.getValue("dept_id");

dataset.getValue("dept_id")既为获取dataset当前记录对应的dept_id的值。同样我们也可以通过dataset的setValue方法修改当前记录的值。

dataset.setValue("dept_id","D12");

它与如下的代码作用是相同的:

var record = dataset.getCurrent();
record.setValue("dept_id", "D12");

dataset.setValue方法表示的是对dataset当前记录执行赋值操作。如果dataset没有记录,则我们需要先插入一条记录,再执行setValue的操作,否则就会报"系统没有当前记录而无法执行赋值操作"。

原理三:记录状态

由于在Client端我们经常会修改dataset中已经下载到客户端的数据,并利用dataset的缓存机制,一次性的批量修改很多条记录,修改的过程中可能会包含对记录的不同操作,如新增记录,修改记录,或删除记录。这些修改在我们利用UpdateCommand或MarmotUpdateCommand对象向Server提交数据之前,全部缓存到Client端的dataset中,由dataset负责管理和维护所有的数据。并给每一条记录添加记录状态管理。记录的状态有:

记录状态内部标示

记录状态含义

new

新增记录,并且还未经过dataset的数据校验机制确认的记录

insert

新增记录,并且已经经过dataset的数据校验机制确认的记录

modify

原始状态为none类型的记录被修改后的状态

delete

原始状态为none类型的记录被删除后的状态

none

记录的原始状态,一般来说从Server利用AJAX技术下载到Client端的记录默认都为none

其中注意new状态的记录不会超过一条,这是因为dataset默认处理机制中,如果连续新增两条记录时,dataset会自动的对第一条新增记录进行数据校验工作,如果成功则允许添加第二条新的记录,如果失败则给出系统提示信息,并终止第二条记录的新增动作。
delete记录状态是用于在client端维护记录时,当我们删除一条记录,dataset并不会将内部的数据真正删除,而只是给当前记录做一个删除标记。使得该记录在界面上变得不可见。实际上dataset的内部还存在该记录对象。
当不同状态下的记录被提交到Server端之后,我们可以通过dataset的RecordIterator对象遍历内部记录,设置RecordIterator的不同过滤方式获取dataset中符合条件的记录,如:

RecordIterator ri = dataset.recordIterator();
ri.setVisibility(Dataset.FILTER_CHANGED);
while (ri.hasNext()) {
Record record = ri.nextRecord();
switch (record.getState()) {
case Record.STATE_NEW://本记录为新增记录
break;
case Record.STATE_MODIFIED://本记录为发生修改的记录
break;
case Record.STATE_DELETED://本记录已经在客户端被用户执行过删除操作
break;
default:
}
}

 

其中提供的过滤方式有:

过滤方式

说明

FILTER_ALL

查看所有记录,包括记录状态为delete的记录

FILTER_CHANGED

查看所有被修改过的记录(包含记录状态为insert、modify和delete的记录),但是不包含记录状态为none的记录

FILTER_DEFAULT

查看默认可见的记录,不包括记录状态为delete的记录

FILTER_DELETED

查看记录状态为delete的记录

FILTER_MODIFIED

查看记录状态为modify的记录

FILTER_NEW

查看记录状态为insert的记录

FILTER_NOT_CHANGED

查看记录状态为none的记录

在dorado的helloworld范例中的数据保存功能实现中我们并没有写一行代码,它是由AutoSqlDataset利用了记录的状态,根据不同的状态选择不同数据更新方式,从而实现自动的批量数据保存功能。

原理四:记录的移动

由于dataset中拥有当前记录的概念,所以当我们将dataset的当前记录移动到另一条记录的时候就会触发dataset的记录移动事件(afterScroll, beforeScroll)同时,dataset也会自动的刷新与它绑定的各个组件对象。例如AutoForm与datatable的联动功能。
具体效果可以参考在线范例:

图例如下:

图表 9
在该范例中我们可以选择表格中的不同行,同时注意观察其他组件的变化(另一个DataTable以及AutoForm)可以看到它们都会保持同步dataset当前记录的移动。并根据当前记录的变化显示当前记录的详细信息。
当dataset中包含多条记录时,我们可以通过如下的方法遍历其中的记录:

dataset.moveFirst();
while (!dataset.isLast()) {

dataset.moveNext();
}

由于dataset与界面组件的绑定关系,当dataset执行以下几个方法实现记录的移动时,都会引起dataset中当前记录的变化:

函数列表

说明

moveFirst()

移动到第一条记录

moveLast()

移动到最后一条记录

moveNext()

移动到当前记录之后

movePrev()

移动到当前记录之前

如果只想遍历dataset的内部记录而不想改变dataset的当前光标,则可以通过如下的代码实现:

var record = dataset.getFirstRecord();
while (record) {

record = record.getNextRecord();
}

原理五:AJAX数据刷新功能(flushData)

Dataset与Server交互所使用的一个很重要的方法是flushData。
这是一个页面无需刷新就可以直接通过框架调用Java类相应的java方法,由该方法负责接受flushData请求,并解析其中的请求参数,从而根据参数将合适的数据返回到Client端,在dorado开发中一般用于实现查询和分页处理。通过flushData处理机制,可以实现很多特效,例如页面不刷新情况下的数据查询功能,数据分批下载,树节点的延迟加载等等。
使用flushData的要点是:

  • 在客户端发出flushData方法之前,将相关的参数信息保存在dataset的parameters集合对象中;
  • 在服务器端对应的方法中获取dataset的parameters信息,并调用自己的业务逻辑代码获取合适的数据并返回到客户端;

有关flushData处理的详细说明,请参考flushData详细使用说明