Glenn Stephens
顾问
2004 年 1 月 本文展示了通过将 ASP.NET 与像 DB2 UDB 这样高性能的、可伸缩的数据库和 Borland Data Providers 相结合,您就可以得到能给人留下深刻印象的数据驱动的 Internet 应用程序,并且所花的时间和编写的代码都非常的少。 简介
如果您像我一样正在开发 Web 应用程序,那么您就需要暴露部分数据库,以便通过一个 Web 浏览器可以看到数据库的这一部分。通过结合使用 Borland C#Builder 和 Borland Data Provider (BDP) 组件,您可以轻松地让 DB2 Universal Database (UDB) 与数据驱动的 Microsoft ASP.NET Web 页面一起运行。对于这个解决方案,我使用 Borland C#Builder Enterprise (或 Architect)、 DB2 UDB V8.1 Personal Edition以及一个兼容 Microsoft ASP.NET 的 Web 服务器。
什么是 ASP.NET?
ASP.NET 是建立在 .NET 平台上的下一代 Web 应用程序框架,是 Microsoft 的 Active Server Pages (ASP) 框架的接替者。ASP.NET 允许以一种类似于 Windows Form 应用程序的方式对 Web 应用程序进行快速应用程序开发(rapid application development,RAD)。在 .NET 平台上创建 Windows 风格的 Web 应用程序这一任务也叫做 WebForms。
要开始 WebForms,您必须将组件放置到一个 WebForm 上,这与典型的 Windows 开发是一样的,然后设置组件的属性和编写组件的事件处理程序。通过这种方式,开发 Web 应用程序非常简单。
从 Borland C#Builder 访问 DB2 — Borland Data Providers (BDP)
创建动态 Internet 应用程序非常容易,但是大多数情况下您还想要开发数据驱动的应用程序,这种应用程序要连接到 DB2 UDB 数据库。正是出于这一点,才有了 BDP 组件。图 1 展示了连接到数据时所需的一些基本组件。连接到 DB2 UDB 所需的所有组件都可以在工具面板(Tool Palette)的 BDP 和 Data Components 页找到。
图 1. 选择 BDP 组件
DB2 UDB 提供了可扩展性、健壮性、易配置性,还有我个人比较喜欢的既可以用 SQL 语言又可以用 Java 语言创建存储过程的能力,因此使用 BDP 组件连接到 DB2 UDB 非常容易。在连接到数据库时要使用的主要组件有 BdpConnection 组件、BdpDataAdapter 组件、BdpCommand 和 DataSet 组件:
图 2. 为数据协同工作的 BDP 组件
DataSet 包含一个表的集合、这些表之间的关系以及其他的信息,例如数据的约束。由 BdpDataAdapter 检索到的查询结果存放在一个 DataTable 中,正是这个 DataTable 对象存放着来自数据库的数据。为简单起见,我们将使用一个单一的 DataSet,这个 DataSet 只包含一个 DataTable。
然而,DataSet 组件只是设计用来在没有与数据库的永久连接的情况下工作。从 BDP 组件中提取数据到 DataSet 中的这一过程首先要求 BdpDataAdapter 连接到数据库,然后 BdpDataAdapter 用一个或多个查询的结果来填充 DataSet 的内容。一旦填充好 DataSet,您就可以断开与数据库的连接。每当需要检索或更新数据库中的数据时,您只需重新连接到 BdpDataAdapter。这样一来,即使没有了到 DB2 UDB 的网络连接,您仍然可以使用数据的一个本地拷贝,以便为到服务器的访问途径重新可用时作准备。
开始构建 Web 应用程序
让我们从开发一个 Web 网格(grid)开始,这个 Web 网格用于显示一个单一数据库查询的结果。首先,需要创建一个新的 Web 应用程序。从 C#Builder IDE 选择 File| New| Other,然后选择一个新的 ASP.NET Web Application。
为应用程序选好了各个选项之后,您就有了一个可以使用的 WebForm。在设计模式中,您可以像在 WYSIWYG 编辑器中编辑 HTML 文档一样来设置屏幕( 见图 3)。
当您开始将 ASP.NET 组件拖放到 Web 表单上时,魔术就真正开始了。在这一页中 ASP.NET 组件和其他元件之间很容易区分,因为 ASP.NET 组件在其左上角通常画有 'asp'。为了开始使用数据,在设计器上拖放一个 DataGrid 组件、一个 BdpConnection 组件和一个 BdpDataAdapter 组件:
图 3. 一个新 Web 表单的示例设置
为了连接到数据库,右键单击 BdpConnection并选择 Connection Editor。从这个菜单中选择 Add按钮,以添加一个数据连接。然后选择您想要连接到的数据库,并为到该数据库的连接创建一个名称。在我的系统上,我将返回一个名为 PRODUCTLIST 的表中所有的条目,这个表在一个名为 SHOPPING 的 DB2 8.1 Personal 数据库中( 参见图 4以了解 BdpConnection 的连接参数)。以下是 PRODUCTLIST 的 DDL:
CREATE TABLE "GLENN "."PRODUCTLIST" (
"PRODUCTCODE" VARCHAR(20) NOT NULL ,
"PRODUCTNAME" VARCHAR(50) NOT NULL ,
"DESCRIPTION" VARCHAR(255) ,
"UNITPRICE" DOUBLE NOT NULL ,
"CATEGORYCODE" INTEGER ,
"IMAGEURL" CHAR(150) )
IN "USERSPACE1" ;
COMMENT ON TABLE "GLENN "."PRODUCTLIST" IS 'A list of Products in the Shopping Cart';
ALTER TABLE "GLENN "."PRODUCTLIST"
ADD CONSTRAINT "CC1053568050795" PRIMARY KEY
("PRODUCTCODE");
|
创建好设置之后,您还需要为数据库连接提供连接设置。一旦定义好了连接设置,您应该就可以在 Connections Editor 中单击 Test按钮来测试是否能够连接成功。
图 4. Connections 编辑器窗体允许您预定义到数据库的连接
如果定义好设置并且可以连接到数据库,这时就可以设置 BdpDataAdapter 组件。回头看看 图 2,您可以看到 BdpDataAdapter 组件和 BdpConnection 及 BdpCommand 对象之间的关系。
BdpDataAdapter 是为使用 BDP 组件而设的强大的代理。BdpDataAdapter 通过 BdpConnection 组件连接到数据库。BdpDataAdapter 组件也有四个 BdpCommand 属性:SelectCommand、InsertCommand、UpdateCommand 和 DeleteCommand。这些 BdpCommands 用于执行对数据库的检索和更新操作。代表 SelectCommand 的命令用于选择用于填充一个 DataTable 的所有数据,而其他三个 BdpCommands 则分别用于表示插入、更新和删除 DataTable 表中的一行记录的数据库操作。
BDP 组件背后的基本概念是,BdpDataAdapter 将使用来自数据库的内容填充 DataSet,以便您可以使用这个 DataSet。然后,应该断开 DataSet 与 BDP 组件的连接。当 DataSet 需要检索更多的数据或者需要更新数据时,它又在必要的时候重新连接到 BdpDataAdapter。现在,您对使用 BDP 组件建立与 DB2 的数据连接这一任务已经有了一个基本的了解,接下来让我们开始将应用程序连接到某些数据。
配置 Data Adapter
为了配置 BdpDataAdapter,在 WebForm 上右键单击 BdpDataAdapter,然后选择 Configure Data Adapter,以弹出 Data Adapter Configuration 对话框:
图 5. Data Adapter Configuration 允许定义将要使用哪个 BdpConnection 组件
在 Select页上,输入用于检索数据的 SQL。在这个例子中,我们将从一个简单的购物车数据库中检索一些数据,特别地,该查询将从 PRODUCTLIST 表中检索一系列的产品。
图 6. 选择一个 DataSet 来填充 DataAdapter
一旦输入了 SQL,您就可以声称您想要 C#Builder 创建一个新的 DataSet 组件(见上面的 图 6),或者使用一个已有的 DataSet 组件,您可能已经将这个组件拖放到 WebForm 上了。Grid 组件将使用这个 DataSet 对象来检索它的数据。您可以根据自己的意愿来创建一个新的 DataSet 或者使用您已经拖放到 WebForm 上的已有的 DataSet。在这个例子中,我们将为应用程序创建一个新的 DataSet。至此,连接数据所需的各个部分都已就绪,我们只需定义数据的表示就可以了。
C#Builder 超快速开发技巧 #1:一旦定义好到 DB2 UDB Database 的连接,从 Data Explorer 选择 Table、 View并将那个表视图或存储过程拖放到 WebForm 上。对于一个 Table 或 View,C#Builder 将自动创建连接到 DB2 UDB 时所需的 BDP 组件。
填充 DataGrid
为了显示这个表示,使用您放置在 Web Form 上的 DataGrid 组件。为了能够在设计时使用 BdpDataAdapter,您将需要将 BdpDataAdapter 组件上的 Active设置为 True,以便网格能够检索您将使用的查询的模式信息。
一旦 BdpDataAdapter 处于激活状态,选择 DataGrid 的 Property Builder 选项。(您可以在属性编辑器中的属性列表下面找到这个选项)。系统将弹出一个对话框,这个对话框用于定义数据连接和显示 DataGrid。
图 7. 定义 DataSet、DataMember 和 DataMember 的主键
DataGrid 的第一个配置选项定义到数据的连接的细节,例如将要使用哪个 DataSet 以及想要显示 DataSet 的哪个 DataMember(DataTable 或 DataView)。您还需要定义 DataMember 中的哪个字段用作 DataView 的关键字段。
至此,为建立数据网格(data grid)而需要做的工作已全部完成。然而,在大多数情况下,您还希望定义将在网格中显示的列。通过选择用于 DataGrid 的 Columns页(见图 8),您可以定义想要显示的列,更改列的顺序,以及定制列标题和列数据的格式。在我的例子中,我将为每个字段重命名标题,并声称 UNITPRICE 字段应该以货币的格式显示。
图 8. 定制和格式化列
现在您和数据驱动的 Web 页面之间就只剩下几行代码了,这几行代码告诉 Web 页面将 DataSet 中的数据绑定到 DataGrid 上。在 ASP.NET 中,带有数据连接的组件在默认情况下是没有连接上的。相反,您必须告诉代码您想要将组件绑定到数据。因此,在 WebForm 的 Page_Load 事件中,使用 DataGrid 的 DataBind 方法来让它连接到数据:
private void Page_Load(object sender, System.EventArgs e)
{
if (!IsPostBack) {
dataGrid1.DataBind();
}
}
|
ASP.NET 使用一种叫做 Post Back 的机制来 Web 表单的状态。当一个 Web 页面第一次被请求时,您将初始化 WebForm 的属性。之后连接数据的用户将使用已经设置好的相同的属性,因此只需要在第一次装载页面时将数据绑定到网格。
一旦为 Page_Load 事件添加了代码,您就可以运行 Web 应用程序了。运行页面之后,您将拥有一个具有专业水准的外观的 Web 页面,这个页面包含了动态 Web 数据:
图 9. 在 Web 浏览器中显示的 DB2 数据
数据绑定——不只是网格
现在您已经试过一次绑定了,您将会喜欢上这种将数据绑定到组件的方式。在这个例子中,只显示一条记录的内容:某一页上某个产品的内容。
首先添加一个新的 ASP.NET 页面到应用程序中,方法是选择 File| New| Other,然后选择一个新的 ASP.NET Page。像以前处理用于网格的结果集一样执行一些相同的步骤,但是这里不是选择一个表中的所有记录,而是只选择一条记录。图 10 展示了针对 SQL 的 Data Adapter Configuration 对话框。注意如何使用问号(?)来表示 SQL 语句中的一个参数:
图 10. 创建一个参数化的查询
一旦定义了 SQL,注意(就像上次一样)创建一个 bdpCommand 对象并将其添加到 WebForm 中,这个 bdpCommand 对象表示该选择查询。由于您已经创建了一个参数化的查询,所以还需定义每个参数所表示的是什么。
选择 BdpCommand 的 Parameters,然后设置这些参数,使它们表示您的数据库查询所需的那些列。要添加一个参数非常简单。对于您需要的每个参数,定义该参数的数据类型、长度,如果需要的话还定义一个名称。对于这个例子,只有一个表示产品编号的参数,这个参数是一个字符串。因此,您需要将该参数对象的 BdpType设置成字符串。因为 PRODUCTCODE 的字段长度是 20 个字符,您还应该将 PRODUCTCODE 字段的数据长度设为 20。
定义好参数之后,您需要为 WebForm 上的组件定义数据绑定。为了将数据绑定到一个组件,首先将那个组件拖放到窗体上,再选择它的 DataBindings(见图 11)。然后定义您想要将数据赋给该组件的哪个属性,以及该属性将从哪个字段获得它的值。
对于像标签(label)这样的组件,您只需将 Label 组件的 Text属性绑定到像 ProductName 这样的一个字段。但是对于 Image 这样的组件,您或许想要将很多不同的字段绑定到不同的属性上。图 11 展示了从数据库中的 IMAGEURL 字段检索的数据字段 URLImage。不仅是这个字段,还有 AlternateText 也要从 PRODUCTNAME 字段检索。
图 11. 使用数据绑定将不同字段绑定到不同的组件属性
因此,您应该能够通过在 URL 的查询字符串中传递产品编号来查看一个数据请求的详细信息。就像 DataGrid 的例子一样,您需要装载页面和绑定数据。因为您将使用一个参数,所以需要使用一个不同的 Page_Load 事件来检索产品编号,将它放到 BdpCommand 中,填充数据,然后将数据绑定到窗体中的组件上:
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
if (!IsPostBack) {
//Get the Product Code from the Query String
string strProdCode = Request.QueryString["ProductCode"];
bdpCommand1.Parameters[0].Value = strProdCode;
bdpDataAdapter1.Fill(dataSet1, "Table1");
this.DataBind();
}
}
|
注意,您可以不对每个数据感知(data-aware)组件使用 DataBind,而是调用 WebForm 的 DataBind 方法,这样将为 WebForm 上的每个组件调用 DataBind 方法。
还应注意的是,我将通过传递要填充的数据集和 Data Table 的名称来对数据集调用 Fill 方法。由于 C#Builder IDE 是自动使用 Table1( 见图 11)的,因此我保留了这样的命名,以避免重新编写代码。
现在所有的数据都连接上了,通过将 ProductCode 放在 URL 中就可以显示一个完整的数据驱动的页面:
图 12. 一个灵活的、数据驱动的 Web 页面
您可以看到,通过使用 .NET 的数据绑定工具,您可以建立强大的数据驱动应用程序并在极短的时间内让应用程序运行起来。
使用内建缓存来提升性能
加快数据驱动的 Web 应用程序的另一个好方法是使用 ASP.NET 的内建缓存特性。如果 Web 应用程序的访问量较大,并且数据是静态的,您就可以利用 ASP.NET 的缓存工具。
通过添加一个 OutputCache 声明到 .aspx 页(这个页面告诉您缓存的规则)中,就可以使缓存工作:
<%@ Page language="c#" Debug="true" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false"
Inherits="MyNewWebApplication.WebForm1" %>
<%@ OutputCache Duration="300" VaryByParam="None" VaryByCustom="browser" %>
|
这里的意思是该页面将存储在缓存中,在对该页面的第一次请求之后的 300 秒(5 分钟)内,随后对该页面的每个请求都将使用这个 Cache。VaryByParam 属性允许您根据查询字符串中的结果来缓存页面结果。对于具有 DataGrid 组件的页面,这样做没有必要,但是对于在 URL 中带有参数的页面(例如 Single 产品页面),这样做就很有用。在显示单个记录的例子中,具有如下所示的代码:
<%@ Page language="c#" Debug="true" Codebehind="WebForm2.aspx.cs" AutoEventWireup="false"
Inherits="MyNewWebApplication.WebForm2" %>
<%@ OutputCache Duration="60" VaryByParam="*" VaryByCustom="browser" %>
|
最后一个属性是 VaryByCustom,这个属性被设置为 'browser',以便专门为某些特定的浏览器缓存值。由于 Web Server 控件在不同的浏览器中会呈现不同的外观,缓存应该只返回专门为客户机浏览器缓存的页面。
一旦您在应用程序中实现了缓存功能,您就可以发现页面装载的速度有了很大的提升。尝试添加缓存技术,您将发现应用程序在性能上的提升。
ASP.NET、DB2 和 C#Builder 的部署问题
准备好 ASP.NET 应用程序后,就需要将它部署到一个支持 ASP.NET 的服务器上,例如 Windows 2000 Server 或者 Windows 2003 Server。与大多数 DB2 数据库应用程序一样,这里需要在要访问数据库的服务器上安装 DB2 客户机。这意味着 ASP.NET 服务器应该安装 DB2 客户机。同样,ASP.NET 服务器需要有 BDP DLLs,以便使用 Borland Data Adapter 组件。
这里需要的主要文件是 Borland.Data.Common.dll 和 Borland.Data.Provider.dll 。您还将需要用于 BDP 的 DB2 提供程序,即 Borland.Data.Db2.dll 。将这个文件安装在支持 .NET 的 Web 服务器上,然后就可以运行应用程序了。
注意:值得一提的是,编写本文时使用的是 C#Builder 的预发行版本,虽然大部分东西还是不变的,但我还是建议您通读 C#Builder 安装目录中的 deploy.txt 文件,以防用 DB2 部署 BDP 时有什么变化。
结束语
通过将 ASP.NET 与像 DB2 UDB 这样高性能的、可伸缩的数据库和 Borland Data Providers 相结合,您就可以得到能给人留下深刻印象的数据驱动的 Internet 应用程序,并且所花的时间和编写的代码都非常的少。
在我的下一篇文章中,我将向您展示如何开始使用与 DB2 UDB 数据库打交道的 ASP.NET Web 服务,以及如何从远程 WinForm 和 WebForm 客户机检索和更新更改。 |