J2EE 数据访问
下面我们将介绍 JDBC API,这是 J2EE 下的行业标准接口集,它允许 Java 程序使用统一的 API 调用集来访问关系数据库。JDBC 允许您开发应用程序一次,然后针对任何 JDBC 相容的数据库部署它们 ―― DB2、Oracle、SQL Server、Sybase、mySQL、Informix 以及其他数据库。
JDBC API 允许任何 Java 组件(包括 Java Servlets 和 JSP 页面)无缝地访问关系数据库中的数据。JDBC 由两部分组成:用于访问数据库的 API,以及数据库厂商为各自的数据库提供的可嵌入 JDBC 驱动程序。JDBC API 最便利的特性之一在于,您不必使用任何特定于厂商的类。您可以在运行时使用一个字符串常量来指定适当的驱动程序,以后就可以使用相同的编程接口,而不管所使用的是哪种数据库。这样您就可以切换数据库,而不必更改代码(只要您在运行时提供字符串常量以指定驱动程序)。
一个 JDBC 例子
典型的 JDBC 应用程序必须完成以下步骤才能与数据库交互:
识别驱动程序。(每个应用程序只需执行这个步骤一次。)
识别数据库并与之建立连接(在需要时提供身份验证信息)。
执行查询和/或更新。
处理结果。
断开与数据库的连接。
清单 29 说明了上述步骤。
清单 29. 一个 JDBC 例子
2 Class.forName("COM.ibm.db2.jdbc.app.DB2Driver");
3 // Step 2. Identify the database and connect to it
4 Connection conn = DriverManager.getConnection("jdbc:db2:SAMPLE","userid","password");
5 // Step 3. Execute query
6 Statement stmt = conn.createStatement();
7 stmt.execute("SELECT * FROM USERID.EMPLOYEE");
8 // Step 4. Get the results
9 ResultSet rs = stmt.getResultSet();
10 while (rs.next()) {
11 String firstCol = rs.getString(1);
12 int secondCol = rs.getInt(2);
13 ...
14 }
15 // Step 5. Disconnect from the database
16 conn.close();
17
清单 29 中的 Step 1 动态地加载适当的驱动程序。这个例子使用的是 DB2;其他 JDBC 驱动程序具有不同的完全限定名称。Step 2 提供特定于驱动程序的 String 指出要连接到哪个数据库。每种 JDBC 驱动程序都有自己的 String 格式。DB2 使用的格式是 "jdbc:db2:DBNAME" ,因此在此例中系统要连接到一个名为 SAMPLE 的数据库。例子中还提供了身份验证信息,以便数据库服务器能够对连接请求进行身份验证。在 Step 4 中,注意例子中如何循环遍历结果集,直到 next() 方法返回 false 。您还必须知道每列的类型,并对每列和每种类型调用适当的 getXXXX(n) 方法。还要注意您传递给 getXXXX(n) 方法的整数是列编号。
在 ASP 页面使用 ADO 但没有连接池时,以上方法与典型的 ASP 页面采用的方法很相似,因为程序员负责打开和关闭数据库连接。
连接池
连接池通过对可以同时打开的数据库连接数目规定上限,可以增加应用程序的可伸缩性,因而防止由于过多的连接请求而造成数据库服务器的过度运行。对于 ASP 来说,如果您选择的数据库(如 DB2、SQL Server 或 Oracle)有 OLEDB 提供程序,则可以利用连接池,从而就不必直接管理数据库连接。
有了 JDBC,您可以将自己从直接管理连接的工作中解放出来。J2EE 应用程序服务器被要求为它们支持的所有数据库提供连接池。它们不使用某些高级的 JDBC API 调用来完成该任务。当您的代码在应用程序服务器的监控下运行时,您就不必直接与数据库服务器交互,以便为每个配置的数据库维护连接池。然后,应用程序从该池中请求连接,并在使用完这些连接之后,将其返回到该池。大多数应用程序服务器都有相当高级的选项对池进行管理,包括“收回”连接的能力,即从出错的应用程序(没有在给定时间内将连接返回池中)取回连接。
使用连接池的应用程序的典型流程如下:
查找应用服务器资源库中的 DataSource (用于访问特定的连接池)。(每个应用服务器都有一个资源库,其中包含所有已配置的连接和其他资源,比如消息队列和 SMTP 提供程序。您可以使用名为 JNDI 的标准 J2EE API 来访问资源库。)(这个步骤只需执行一次。)
从池中获得连接(在需要时提供身份验证信息)。
执行查询和/或更新。
处理结果。
将连接返回池中。
清单 30 展示了使用连接池的一个例子。
清单 30. 一个连接池例子
2 InitialContext ic = new InitialContext();
3 DataSource ds = (DataSource) ic.lookup("jdbc/MyDS");
4 // Step 2. Get a connection from the pool
5 Connection conn = ds.getConnection();
6 // Step 3. Execute query
7 Statement stmt = conn.createStatement();
8 stmt.execute("SELECT * FROM USERID.EMPLOYEE");
9 // Step 4. Get the results
10 ResultSet rs = stmt.getResultSet();
11 while (rs.next()) {
12 String firstCol = rs.getString(1);
13 int secondCol = rs.getInt(2);
14 ...
15 }
16 // Step 5. Return connection to the pool
17 conn.close();
18
Step 1 假设应用服务器已经配置了名为 "jdbc/MyDS" 的 DataSource 。这样就封装了一个特定的 JDBC 驱动程序和数据库。您还可以向 DataSource 定义添加身份验证信息,这样应用程序就不必提供该信息。您可以使用 InitialContext 类(它是 JNDI API 的一部分)来查找应用服务器控制的各种资源。Step 3 至 Step 5 与前一个例子相同,不过要注意 Step 5 中对 close() 方法的调用仅把连接返回池中,而不是关闭该数据库连接。