深入CursorAdapter(一)
来源:优易学  2011-12-9 18:18:26   【优易学:中国教育考试门户网】   资料下载   IT书店

 

  优点

  有大量的理由支持我们使用 CursorAdapters 来代替远程视图、SPT、ADO 或者 XML:
  ×× 每一种机制都有一种不同的接口。对于远程视图,你用 USE 命令来打开它们。对于SPT,你要使用 SQLCONNECT() 和 SQLEXEC() 来建立一个 Cursor。对于 ADO,你必须先建立 ADO 的 Connection 对象和 Recordset 对象(根据你取得数据方式的不同,也许还可能需要一个 Command 对象)的实例,并调用它们的 Open 方法。对于 XML,你首先必须从什么地方获得一个 XML 字符串(例如在 N 层应用中通过一个 COM 部件,或者在 SQL Server 中通过 SQLXML),然后使用 XMLTOCURSOR() 来把这个字符串转换成一个 VFP 的 Cursor。编写对后台数据源进行更新的代码也各不相同。所以,当你从一种机制转换到另一种机制的时候,就必须要去学一种新的技术,还有你可能需要重写的大量已有的代码。
  不管你使用哪种机制来取得数据,CursorAdapters 都使用同一个统一的接口。通过设置该对象的一些属性,然后调用它的 CursorFill 方法来取得数据,对这个 Cursor 操作时就像在操作一个普通的 VFP Cursor 一样,然后调用 TABLEUPDATE() (或者让VFP自动去处理它)来将更新提交到后台数据源。
  ×× 在实际开发的时候,你经常会需要从命令窗口中打开一个 Cursor 来浏览它的内容。对于远程视图,这么做是很简单的,但是对于 SPT、ADO 和 XML,就可能要花上很多力气了。
  而打开由一个 CursorAdapter 的子类产生的 Cursor 几乎就像打开一个远程视图那么容易:你只需要建立这个子类的实例,然后调用它的 CursorFill 方法就行了。你甚至可以直接在它的 INIT 方法中进行 CursorFill,这样只要一步就可以完成操作了。

  ×× 对于远程视图来说,升迁一个已有的应用程序会相对容易一些:你只要把数据环境中本地表或视图的东西换成同名的远程视图就行了。但是对于SPT、ADO 或 XML,你可能就必须要全部重写整个数据访问方案了。
  而用 CursorAdapters 来升迁一个应用程序就会象用 远程视图来升迁一样轻松——只要简单的把数据环境中的 Cursor 对象替换成 CursorAdapters 对象就行了。
  ×× 在表单和报表设计器中使用远程视图来工作是很容易的。你可以给数据环境添加一个远程视图,然后就能利用到数据环境提供的可视化设计的优势了:拖放字段来自动建立控件、通过在属性窗口中的组合框中选择来轻松的将控件绑定到一个字段等等。SPT、ADO、XML 就不支持可视化设计方式了。
  CursorAdapters 与远程视图一样能够享受到在数据环境中可视化设计的那些优点。
  ×× 用视图设计器可以很容易的建立远程视图。尽管过去它有着许多限制,尤其是在处理有两个以上的表相互连接的视图的时候,可现在,VFP 8 已经修正这些问题中的大多数,并且添加了许多新功能,例如双向编辑:你可以在 SQL 窗口中修改代码,然后就能看到这些改动被反映到视图设计器的可视化部分中了。而对于 SPT、ADO 和 XML,要做的工作就多的多,因为每样东西你都必须自己写代码:建立和关闭连接、要执行的 SQL Select 语句等等。
  VFP 8 包含了一个 CursorAdapters 生成器,用了它,可以只需要很少的工作就可以设置好那些对于取得和更新数据来说相当重要的属性。它甚至还包含了一个 SelectCmd 生成器,这个生成器的可视化程度就像是视图设计器一样,它让你可以通过使用一个“mover”控件来选择应该从远程表中取得那些字段。
  ×× 将远程视图和ADO 记录集中的更新提交到后台数据库是相当简单的。假定视图的属性已经被设置正确了,那么你只需要调用 TABLEUPDATE() 就可以了。在 ADO 的情况下,则调用 RecordSet.Update() 或者 UpdateBatch()。对于 SPT 和 XML,你就必须手工的做大量工作来把更新提交到后台。
  象我们前面看到的那样,用 CursorAdapter 来提交更新只需要设置几个属性,然后就可以全部交给 VFP 去做其它所有的工作,或者你也可以很方便的通过指定怎么删除、插入和更新来获得更大的灵活性。
  ×× 由于远程视图和 SPT 建立的结果集是 VFP 的 Cursor,所以你可以在VFP中的任何地方使用它们:表格、报表、用 Scan 来遍历等等。而另一方面的 ADO 和 XML ,在使用之前就必须先把它们转换成 Cursor,这会给你的应用程序增加额外的复杂性和处理它们的时间。
  CursorAdapter 的结果集是一个 VFP Cursor,所以它有着与远程视图和SPT同样的优势。而更棒的是,即使数据源是 ADO 和 XML 你也能得到一个 VFP 的 Cursor,因为 CursorAdapter 会自动为你处理好转换的事情并为你形成一个 Cursor。
  ×× 由于一个远程视图的 SQL Select 语句是预先定义好的,所以你无法动态去修改它。尽管对于那些典型的数据输入表单来说这已经足够了,但是对于查询和报表来说则不然。可能你必须要建立好几个从同一个表中取得数据的视图,每一个会选择不同的字段、使用不同的 WHERE 子句结构等等。对于 SPT、ADO 或 XML 来说,这不是一个问题。
  CursorAdapters 不会受这个问题的折磨——你可以很轻松的通过改动 SelectCmd 属性来改变取得什么数据以及怎么取得数据。
  ×× 你不能从一个远程视图中调用存储过程,所以远程视图需要直接访问后台的表。对于你的应用程序的数据库管理员来说,这可能是一个问题——某些数据库管理员认为,基于安全的或者什么其它原因,所有的数据访问应该只通过存储过程来进行。而且,由于存储过程是在后台预编译的,所以它执行起来通常要比 SQL Select 语句快得多。在 SPT、ADO 和 XML 的情况下,你可以根据需要来调用存储过程。
  通过简单的设置 SelectCmd 属性,CursorAdapters 也可以使用存储过程。
  ×× 远程视图保存在一个数据库容器中,所以还有一套你必须维护和安装到客户系统上的文件。此外,当你打开一个视图的时候,VFP 会试图去锁定在 DBC 中的视图的记录,虽然这只需要很短的时间。在一个忙碌的系统中,当几个用户试图同时打开一个表单的时候,这可能会造成冲突。尽管也有一些变通的处理办法(把DBC拷贝到本地工作站上、或者使用在 VFP 7 以上版本中的 SET REPROCESS SYSTEM 来减少锁定的时间),这总是一件你要操心的事情。还有一个问题是:如果你使用一个 SELECT * 的视图来从一个指定的表取得数据、而那个表的结构又在后台被改动过了,那么这个视图就会变得无效而且必须要重建才能解决。对于 SPT、ADO 和 XML 来说,由于它们与 DBC 无关,因此它们都没有这些问题。
  因为它们都不在 DBC 里面,所以 CursorAdapters 就也没这些问题了。
  ×× 由于远程视图和 SPT 是通过 ODBC 来工作的,因此它们只能用于直接数据连接的“客户—服务器”模式。而ADO和XML有着在一个 N-层应用程序中的多个层之间传递数据的机制可供选择。
  由于 CursorAdapters 可以建立来自 ADO 或者 XML 数据的 VFP Cursor,因此它对于在一个 N-层应用程序中被用于用户界面层来说是理想的。

  总结
  ××
  我认为 CursorAdapters 是 VFP 8 中最重要、最令人兴奋的增强之一,因为它提供了一个对于远程数据源的统一而又容易使用的接口,此外,象我们将要在以后的文章中讲述的那样,它还允许我们建立可重用的数据类。下个月我们将探讨一下访问本地数据或者使用 ODBC、ADO和XML来访问远程数据的细节。再下个月,我们将探讨一下建立可重用数据类、以及怎样在报表中使用 CursorAdapters。

  【译者注】
  附带的示例文件是一个PRG,实在太简单了,我就直接把内容贴在这里了。

  local lcConnString,
  loCursor as CursorAdapter,
  laErrors[1]
  lcConnString = 'driver=SQL Server;server=(local);database=Northwind;' +
  'uid=sa;pwd=;trusted_connection=no'
  * change password to appropriate value for your database
  loCursor = createobject('CursorAdapter')
  with loCursor
  .Alias = 'Customers'
  .DataSourceType = 'ODBC'
  .DataSource = sqlstringconnect(lcConnString)
  .SelectCmd = "select CUSTOMERID, COMPANYNAME, CONTACTNAME " +
  "from CUSTOMERS where COUNTRY = 'Brazil'"
  .KeyFieldList = 'CUSTOMERID'
  .Tables = 'CUSTOMERS'
  .UpdatableFieldList = 'CUSTOMERID, COMPANYNAME, CONTACTNAME'
  .UpdateNameList = 'CUSTOMERID CUSTOMERS.CUSTOMERID, ' +
  'COMPANYNAME CUSTOMERS.COMPANYNAME, CONTACTNAME CUSTOMERS.CONTACTNAME'
  if .CursorFill()
  browse
  else
  aerror(laErrors)
  messagebox(laErrors[2])
  endif .CursorFill()
  endwit

上一页  [1] [2] 

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训