JBuilder开发人员指南 第12章:过滤、排序与定位数据

《JBuilder开发人员指南》中译本第 12 章(15 页),讲 JBuilder DataExpress 数据集的三大操作:过滤、排序、定位。核心思想:数据操作独立于数据获取方式——不管用 QueryDataSet、TableDataSet 还是任何 StorageDataSet 子类,操作和控件绑定方式完全一致。

12.1 提供数据(教程基础)

本章所有教程的基础配置:Database 组件(Connection URL: jdbc:odbc:DataSet Tutorial,SYSDBA/masterkey,连 Local InterBase 示例 employee 表)+ QueryDataSet 组件(SQL:SELECT EMP_NO,FIRST_NAME,LAST_NAME FROM EMPLOYEE WHERE EMP_NO<10)+ GridControl/NavigatorControl/StatusBar 三个 JBCL 控件,均绑定 dataSet 属性。EMPLOYEE 表 42 条记录 11 列,SQL 限制了取到数据集里的行列数。

12.2 过滤数据

  • 过滤只是暂时隐藏数据集中的行,底层 dataset 不变,改的是当前视图;响应用户请求或程序逻辑(如保存前显示所有被删记录)。
  • 两种过滤层次:
    1. 服务器端过滤:SQL 里加 WHERE 子句,直接限制从服务器提取的数据。
    2. 数据集端过滤:RowFilterListener 挂到 DataSet 的 filterRow 事件上,每行调用一次,缺省排除行——想包含必须显式调用 RowFilterResponse.add()。
  • 教程(FilterRows.jpr):两个 TextFieldControl(列名 + 匹配值)+ ButtonControl(actionPerformed 里重挂 filter 适配器触发过滤);列名或值留空即取消过滤显示全部行。
  • 用 DataSetView 可以对同一数据集同时开多个过滤视图。

12.3 排序数据

  • 排序定义一个索引让数据按序显示,不实际重排服务器表中的行。多列排序:先主列,键值重复时按次列,依此类推;最后仍重复的按服务器原序。
  • 规则:大小写只对 String 列有效;方向(升/降)按列设置;降序时 null 排最上,升序排最下。
  • GridControl/JdbTable 运行时单击列标题排序(再击切换升降序),sortOnHeaderClik 属性可关闭;这种交互式排序一次只能排单列。
  • 可视化设置:Inspector 双击 DataSet 的 sort 属性 → SortDescriptor 编辑器(选列、大小写、升降序、唯一、索引名),生成 SortDescriptor 代码;setSort(null) 恢复无序视图。
  • 唯一(Unique):是在数据集上的约束而不只是索引——单列唯一索引保证该列无重复值;施加唯一 sort 时,违反约束的重复行被拷贝到一个独立 DataSet,可用 StorageDataSet.getDuplicates() 取出、deleteDuplicates() 删除。上一轮唯一 sort 的副本 DataSet 未删除时,新的唯一 sort 设置无效(防止误删有价值行)。多列唯一时约束作用于列组合(单列可重复,组合不可)。
  • 命名索引:给排序要求起名字。索引是 maintained(维持排序次序和唯一约束,即使当前按别的次序查看数据)——例如在 CustNo 列定义过唯一排序后,即使改按邮编查看,仍不能输入重复 CustNo。sort 属性设为与当前排序参数相同的 SortDescriptor 时会复用现有排序。

12.4 定位数据

  • 两种方式:
    1. 交互式:JBCL LocatorControl 组件,columnName 属性指定定位列(不设则作用于 UI 控件的最后列);对 String 列有增量搜索;提示信息显示在同绑定的 StatusBar 上。可用 TextFieldControl 的 keyPressed 事件(检测 Enter)动态指定定位列;↑/↓键执行 locate prior/next。示例 Locator.jpr。
    2. 程序定位:locate(ReadRow, int) 方法,int 参数为 Locate 类操作常量。
  • 程序定位流程:初始化 DataRow → 给要找的列赋值 → locate(dataRow, Locate.FIRST) → 测试返回值,再用 NEXT/LAST 等继续找。
  • locate() 只在 DataSet 的当前视图内查找(被 RowFilterListener 排除的行不参与);若视图已排序,按排序序列匹配。找 null 值:DataRow 中包含该列但不赋值。
  • DataRow:只存一行数据的类,与 DataSet 同为 ReadWriteRow 子类,继承 getInt/setInt 等同套方法。缺省所有列参与定位;要排除某些列,用 scoped 构造器 DataRow(DataSet, String) 或 DataRow(DataSet, String[]) 只含指定列。
  • Locate 选项(com.borland.dx.dataset.Locate 类,可按位 OR 组合):
    • 起点方向四选一(必选,否则抛 NEED_LOCATE_START_OPTION):FIRST(从头向下)、LAST(从尾向上)、NEXT(当前向下)、PRIOR(当前向上)。
    • FAST / NEXT_FAST / PRIOR_FAST:定位值不变时无需重复从 DataRow 读取,循环找所有匹配行时用 FIRST 找第一个,再循环 NEXT_FAST 直到返回 false。
    • CASE_INSENSITIVE:字符串忽略大小写匹配,仅对 String 列有意义,多列定位时作用于所有 String 查找列。
    • PARTIAL:前缀匹配(定位值”M”匹配所有 M 开头姓名)。多列 PARTIAL 定位列次序任意变化,只作用于最后指定的列;其余列须完全匹配,末列非 String 时抛 PARTIAL_SEARCH_FOR_STRING。
  • 通用类型定位:DataExpress 数据用 Variant 对象保存,通用代码用 setVariant()/getVariant() 操作任意类型列,显示时配 JBCL 格式类。

关联