JDBC 简介
1996 年,Sun 发布了 Java 数据库连接 (JDBC) 工具包的一个版本。这个软件包允许程序员使用 Java 连接、查询和更新数据库,使用的语言是结构化查询语言 (SQL)。与其他的数据库编程环境相比,Java 和 JDBC 的结合使用具有优势。使用 Java 和 JDBC 开发的程序是平台和供应商独立的,即,同一个 Java 程序可以在 PC、工作站或网络计算机上运行。此外,数据库可以从一个数据库服务器转移到另一个数据库服务器,并且可以使用相同的 Java 程序而无需修改。本文讨论了如何将 JDBC 与 MySQL 数据库一起使用。(请参阅 Reuven Lerner 在 1997 年 9 月、10 月和 11 月的 LJ 杂志上的“At the Forge”专栏。)
许多数据库技术,例如事务处理、触发器和索引,都得到了 JDBC 的支持。但是,这些主题超出了本文的范围。由于 JDBC 软件包相对较新,数据库开发人员期望的工具,例如报表生成器、查询构建器和表单设计器,都已可用。在不久的将来,应该会有更多的工具可用。尽管缺少工具,但使用 JDBC API 开发高度交互式的网页是可能的,而且复杂度不高。
JDBC 背后的思想与 Microsoft 的开放数据库连接 (ODBC) 类似。ODBC 和 JDBC 都基于 X/Open 数据库连接标准。使用 JDBC API 编写的程序与 JDBC 驱动程序管理器通信,后者使用当前加载的驱动程序。
可以使用两种架构与数据库通信(参见图 1)。第一种架构中,JDBC 驱动程序直接与数据库通信。驱动程序代表 Java 程序连接到数据库并执行 SQL 语句。结果从驱动程序发送回驱动程序管理器,最终发送到应用程序。
在另一种架构中,JDBC 驱动程序通过“桥接器”与 ODBC 驱动程序通信。单个 JDBC 驱动程序可以与多个 ODBC 驱动程序通信。每个 ODBC 驱动程序都为特定的数据库执行 SQL 语句。结果像以前一样沿链向上发送。
开发 JDBC/ODBC 桥接器的目的是为了利用大量支持 ODBC 的数据源。桥接器将 JDBC 调用转换为 ODBC 调用,并将它们传递给后端数据库的相应驱动程序。这种方案的优点是应用程序可以访问来自多个供应商的数据。但是,由于增加了开销,JDBC/ODBC 桥接器的性能比单独的 JDBC 驱动程序慢。数据库调用必须从 JDBC 转换为 ODBC,再转换为本机 API。
使用没有桥接器的 JDBC 驱动程序所需的操作更少。图 2 显示了从 applet 使用 JDBC 驱动程序访问数据库的步骤。Gwe JDBC 驱动程序与 MySQL 数据库一起使用。JDBC 驱动程序类首先从 Gwe 主机站点下载。接下来,applet 逻辑将 JDBC 调用传递给驱动程序管理器,驱动程序管理器又将调用传递给 JDBC 驱动程序。JDBC 驱动程序打开与 MySQL 数据库服务器的 TCP/IP 连接。数据通过连接来回传输。数据库处理完成后,连接关闭。
JDBC API 可以用于 applet 和独立应用程序。除了 applet 的通常限制外,只接受来自下载 applet 的同一服务器的连接。如果 Web 服务器和数据库服务器不在同一台机器上,则 Web 服务器必须运行代理服务来路由数据库流量。独立应用程序可以访问本地信息和远程服务器。
MySQL 数据库的 JDBC 驱动程序的安装很简单。该软件可以从 Gwe Technologies 的 http://www.gwe.co.uk/ 下载。版权声明允许重新分发源代码和二进制文件,但与 GNU 许可证不同。下载文件 exgweMysqlJDBC.0.9.2-src.tar.gz。它包含 Gwe MySQL JDBC 驱动程序的源代码和类文件。
JDBC 的使用需要访问 pre-1.1 Java Development Kit 中不可用的 java.sql 类。这些类已重命名并包含在 /exjava 目录中。另一个目录 /exgwe 包含 Gwe MySQL JDBC 驱动程序的源代码和类。这些类使用 exjava 目录中的类。将解压 tar 文件的目录添加到 CLASSPATH 环境变量中,JDBC 驱动程序的安装就完成了。
此示例(如 列表 1 所示)假定您对 Java 有一定的了解。Java 代码加载 JDBC 驱动程序类,建立与数据库的连接,构建 SQL 语句,提交语句并检索结果。必须存在数据库和填充了一些数据的表。
在第一条可执行行中,通过将其完全限定的名称传递给 Class.forName 方法来加载 JDBC 驱动程序的类对象。此方法加载类(如果尚未加载),并为其返回 Class 对象。在下一行中,数据库 URL 字符串以 jdbc:子协议名称: 主机名:端口/数据库名称/其他参数 的形式构建。子协议名称是 mysql,因为我们使用的是 MySQL 数据库。在本例中,主机名是 localhost,但也可以是 Internet 主机名或 IP 地址。MySQL 服务器的端口号是 3306,数据库的名称是 test。其他参数可以在数据库 URL 中传递,例如用户 ID 和密码。
通过调用驱动程序管理器的 getConnection 方法获得连接对象,从而允许使用 JDBC 驱动程序来管理查询。用户 ID 和密码在文件中以明文形式存在。密码在将信息传递给 MySQL 服务器之前由 JDBC 驱动程序加密。需要语句对象来发出查询。语句对象通过调用连接对象的 createStatement 方法获得。
SQL 查询存储在字符串中,并传递给语句对象的 executeQuery 方法,该方法返回包含查询结果的 ResultSet 对象。resultSet 对象的 next 方法将当前行向前移动一行。在最后一行之后,它返回 false。必须调用此方法以前进到第一行,并且可以在循环中调用以从所有匹配的行中检索数据。resultSet 对象包含许多从行中提取数据的方法。例如,要检索字符串,可以使用 getString 方法。类似地,要检索整数,可以使用 getInt 方法。还包括检索字节、short、long、float、double boolean、date、time 和 blob 的其他方法。getBytes 方法可用于检索二进制大对象 (blob)。这些方法的参数是整数或字符串。整数是检索到的行的列号。并非表的所有列都需要检索。字符串是列标签的名称。
从 resultSet 对象中提取数据后,将其关闭。可以发出另一个 SQL 查询,并且可以重用 resultSet 对象。语句对象也可以重用。当数据库检索完成时,语句和连接对象关闭。这个简单的示例说明了从数据库表中检索数据的过程。也可以更新表并获取有关表的信息。更新表时,使用语句对象的 executeUpdate 方法。例如
String query = "update test_table set phone = 999-9999 "; query += "where name = \"John Smith\""; stmt.executeUpdate( query );
JDBC 可用于获取有关数据库及其表的结构的信息。例如,您可以获取特定数据库中的表列表以及任何表的列名。在为任何数据库编程时,此信息都很有用。程序员可能不知道数据库的结构,但可以通过使用元数据语句来获取,元数据语句是用于描述数据库及其部分的 SQL 语句。
可以使用 JDBC 检索两种类型的元数据。第一种类型描述数据库,第二种类型描述结果集。DatabaseMetaData 类包含一百多种查询数据库的方法,其中一些方法非常特殊。一个常用的方法是 getTables 方法。
DatabaseMetaData dmd = con.getMetaData(); ResultSet rs = dmd.getTables( null, null, null, new String[] {"TABLE"} );
传递给 getTables 的参数依次是目录(相关模式的组)、模式(相关表的组)模式、表名模式和类型数组。某些类型包括表、视图和系统表。如果传递 null,则不使用模式来限制检索到的元数据信息。其他一些方法包括 getDataProductVersion、getTablePrivileges 和 getDriverName。结果集 rs 包含有关数据库中所有表的信息。每一行都包含有关表的信息。例如,结果集任何行的第三列都是表名字符串。
执行查询后,可以获得有关结果集的有用元数据。当在执行查询后获得结果集时,可以使用元数据语句来提取信息,例如列数、列类型和宽度。
ResultSet rs = stmt.executeQuery("Select * from test_table"); ResultSetMetaData rsmd = rs.getMetaData();
rsmd.getColumnCount() 方法返回 test_table 中的列数,rsmd.getColumnLabel(i) 方法返回第 i 列的名称。类似地,rsmd.getColumnDisplaySize(i) 方法返回第 i 列的宽度。JDBC API 中描述的许多其他方法可用于提取有关表的所有类型的信息。
在 Mitre,我们使用商业搜索引擎(如 Altavista 和 Lycos)从 Internet 收集各种主题的信息。这些信息以任何主题的文本文档集合的形式存储,并且可以通过关键字搜索。我们使用亚利桑那大学的公共领域搜索引擎 Glimpse 来索引和搜索文档集合。
一些文档集合可能相当大(超过 1500 个文档)。如果输入一个常用关键字,则匹配文档的列表将很大。我们使用 Java 和 JDBC 显示搜索引擎的结果,以避免扫描长长的匹配文档列表。Java 用于构建 3D 空间,并在表示关键字在文档中出现频率的位置绘制圆圈。JDBC 用于检索存储在表中的文档标题。将集合中所有文档的所有标题作为参数传递给 Java applet 会显着增加加载 applet 的时间。
Glimpse 返回关键字在文档中出现的频率。我们使用该数字在 3D 空间中定位表示文档的圆圈(参见图 3)。每个轴代表一个关键字。如果输入的关键字少于三个,文档将显示在一个平面上或一条线上。如果输入的关键字超过三个,则必须选择三个或更少的关键字才能显示匹配的文档。
关键字的出现频率针对每个轴进行归一化,文档中关键字的频率作为参数传递给 applet。圆圈的颜色是根据圆圈在三个轴中的位置计算的。红色用于 z 轴上的文档,绿色用于 y 轴上的文档,蓝色用于 x 轴上的文档。对于关键字频率较高的文档,使用三种原色的较亮色调。对于包含多个关键字的圆圈,使用原色的混合色。
JDBC 用于检索包含关键字非零出现次数的文档的标题。当使用相当独特的关键字时,此数字通常少于文档总数。当鼠标位于文档上方时,会显示一个窗口,其中包含文档的标题。有时,多个文档可能具有相同的关键字出现频率。在这种情况下,窗口会显示多个文档的标题。圆圈的颜色变为白色,以指示鼠标所在位置的文档。提供了一个单击窗口中框的选项,它将在单独的窗口中检索与文档对应的文本。
本文介绍了在 Linux 下使用 JDBC 的基础知识:JDBC 的设计、MySQL 的 JDBC 安装以及检索/存储数据的示例代码。元数据语句可用于查询数据库及其表的结构。最后,我们看了一个使用搜索引擎与 JDBC 和 Java 的示例。通过 Java applet 查看结果,使用户的任务比通过 CGI 程序更有趣。
本文中引用的列表可以通过匿名下载文件 ftp.linuxjournal.com/pub/lj/listings/issue55/2846.tgz 获得。
Manu Konchady (manuk@mitre.org) 在 Mitre 公司工作,开发信息检索软件。作为 50 人小组中唯一的 Linux 用户,他正在努力推广 Linux 的诸多好处。