Servlet、JSP与数据库操作的全面指南
1. JDBC基本使用步骤
JDBC(Java Database Connectivity)是Java与数据库进行交互的标准API。使用JDBC进行数据库操作通常包含以下步骤:
1. 加载JDBC驱动 :可以参考 http://java.sun.com/products/jdbc/drivers.html 获取可用的驱动。示例代码如下:
Class.forName("package.DriverClass");
Class.forName("oracle.jdbc.driver.OracleDriver");
- 定义连接URL :具体的格式会在特定驱动的文档中定义。以下是Oracle和Sybase数据库的连接URL示例:
String host = "dbhost.yourcompany.com";
String dbName = "someName";
int port = 1234;
String oracleURL = "jdbc:oracle:thin:@" + host + ":" + port + ":" + dbName;
String sybaseURL = "jdbc:sybase:Tds:" + host + ":" + port + ":" + "?SERVICENAME=" + dbName;
- 建立连接 :
String username = "jay_debesee";
String password = "secret";
Connection connection = DriverManager.getConnection(oracleURL, username, password);
可选的操作是使用 Connection 的 getMetaData 方法查找数据库信息:
DatabaseMetaData metaData = connection.getMetaData();
String databaseProductName = metaData.getDatabaseProductName();
String databaseProductVersion = metaData.getDatabaseProductVersion();
String driverName = metaData.getDriverName();
String driverVersion = metaData.getDriverVersion();
- 创建语句对象 :
Statement statement = connection.createStatement();
- 执行查询或更新 :
String query = "SELECT col1, col2, col3 FROM sometable";
ResultSet resultSet = statement.executeQuery(query);
- 处理结果 :使用
next方法获取新行,使用getXxx(index)或getXxx(columnName)提取行中的值。第一列的索引是1,而不是0。
while(resultSet.next()) {
System.out.println(resultSet.getString(1) + " " +
resultSet.getString(2) + " " +
resultSet.getString(3));
}
- 关闭连接 :
connection.close();
1.1 数据库工具方法
DatabaseUtilities 类中包含一些静态方法,用于简化数据库操作:
- getQueryResults :连接到数据库,执行查询,将所有行作为字符串数组检索,并将它们放在 DBResults 对象中。该方法有两个版本,一个创建新连接,另一个使用现有连接。 DBResults 有一个简单的 toHTMLTable 方法,可将结果输出为HTML表格,也可作为Excel电子表格使用。
- createTable :根据表名、列格式字符串和行值数组,连接到数据库,删除指定表的现有版本,使用指定格式发出 CREATE TABLE 命令,然后为每一行发送一系列 INSERT INTO 命令。同样有两个版本,一个创建新连接,另一个使用现有连接。
- printTable :根据表名连接到指定数据库,检索所有行并打印到标准输出。它通过将表名转换为 SELECT * FROM tableName 形式的查询,并传递给 getQueryResults 来检索结果。
- printTableData :根据之前查询得到的 DBResults 对象,将其打印到标准输出。这是 printTable 方法的底层方法,也可用于调试任意数据库结果。
1.2 预编译语句
预编译语句(Prepared Statements)可以提高性能和安全性,使用步骤如下:
1. 创建预编译形式 :使用 connection.prepareStatement 方法,用问号标记参数。
String template = "UPDATE employees SET salary = ? WHERE id = ?";
PreparedStatement statement = connection.prepareStatement(template);
- 指定查询参数 :使用
statement.setXxx方法。
statement.setFloat(1, 1.234);
statement.setInt(2, 5);
- 执行操作 :
statement.execute();
2. 数据库连接池的实现步骤
数据库连接池可以提高数据库操作的性能,以下是实现连接池的步骤:
1. 预分配连接 :在类的构造函数中执行此任务,从Servlet的 init 方法调用构造函数。使用向量存储可用的空闲连接和不可用的繁忙连接。
availableConnections = new Vector(initialConnections);
busyConnections = new Vector();
for(int i = 0; i < initialConnections; i++) {
availableConnections.addElement(makeNewConnection());
}
- 管理可用连接 :如果需要连接且有空闲连接可用,将其放入繁忙连接列表并返回。繁忙列表用于检查连接总数的限制,以及在需要显式关闭所有连接时使用。当丢弃一个连接时,使用
notifyAll方法通知所有等待的线程。
public synchronized Connection getConnection() throws SQLException {
if (!availableConnections.isEmpty()) {
Connection existingConnection = (Connection)availableConnections.lastElement();
int lastIndex = availableConnections.size() - 1;
availableConnections.removeElementAt(lastIndex);
if (existingConnection.isClosed()) {
notifyAll();
return getConnection();
} else {
busyConnections.addElement(existingConnection);
return existingConnection;
}
}
}
- 分配新连接 :如果需要连接,没有空闲连接可用,且未达到连接限制,则启动一个后台线程分配新连接。然后等待第一个可用连接,无论是否是新分配的连接。
if ((totalConnections() < maxConnections) &&!connectionPending) {
makeBackgroundConnection();
try {
wait();
} catch(InterruptedException ie) {}
return getConnection();
}
- 等待连接可用 :当没有空闲连接且达到连接数量限制时,使用
wait方法等待,该方法会放弃线程同步锁并暂停线程,直到调用notify或notifyAll方法。
try {
wait();
} catch(InterruptedException ie) {}
return getConnection();
- 根据需要关闭连接 :虽然连接在垃圾回收时会关闭,但有时需要更明确地控制该过程。
public synchronized void closeAllConnections() {
closeConnections(availableConnections);
availableConnections = new Vector();
closeConnections(busyConnections);
busyConnections = new Vector();
}
2.1 连接池性能测试结果
以下是不同条件下连接池的平均响应时间:
| 条件 | 平均时间 |
| — | — |
| 慢速调制解调器连接到数据库,10个初始连接,50个最大连接(ConnectionPoolServlet) | 11秒 |
| 慢速调制解调器连接到数据库,回收单个连接(ConnectionPoolServlet2) | 22秒 |
| 慢速调制解调器连接到数据库,无连接池(ConnectionPoolServlet3) | 82秒 |
| 快速LAN连接到数据库,10个初始连接,50个最大连接(ConnectionPoolServlet) | 1.8秒 |
| 快速LAN连接到数据库,回收单个连接(ConnectionPoolServlet2) | 2.0秒 |
| 快速LAN连接到数据库,无连接池(ConnectionPoolServlet3) | 2.8秒 |
连接池操作流程 mermaid 流程图
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始]):::startend --> B(预分配连接):::process
B --> C{需要连接?}:::decision
C -- 是 --> D{有空闲连接?}:::decision
D -- 是 --> E(将空闲连接移到繁忙列表):::process
E --> F(返回连接):::process
D -- 否 --> G{达到连接限制?}:::decision
G -- 否 --> H(启动后台线程分配新连接):::process
H --> I(等待连接可用):::process
I --> C
G -- 是 --> I
C -- 否 --> J{需要关闭连接?}:::decision
J -- 是 --> K(关闭所有连接):::process
J -- 否 --> C
F --> L(使用连接进行操作):::process
L --> M(操作完成):::process
M --> N(将连接移回空闲列表):::process
N --> C
K --> A
3. 其他相关技术要点
3.1 HTTP请求和响应头
HTTP请求和响应头在Web应用中起着重要作用,以下是一些常见的请求和响应头:
- 请求头 :
- Accept-Charset :指定客户端接受的字符集。
- Accept-Encoding :指定客户端接受的编码方式,如 gzip 。
- Authorization :用于身份验证。
- Cookie :包含客户端发送的Cookie信息。
- 响应头 :
- Content-Encoding :指定响应内容的编码方式。
- Content-Language :指定响应内容的语言。
- Set-Cookie :用于设置Cookie。
3.2 JSP指令和脚本元素
JSP(JavaServer Pages)是一种用于创建动态Web页面的技术,包含以下指令和脚本元素:
- 指令 :
- include :在页面翻译时或请求时包含其他文件。
- page :设置页面的属性,如字符编码、会话支持等。
- taglib :引入自定义标签库。
- 脚本元素 :
- 声明 :用于声明变量和方法。
- 表达式 :用于输出表达式的值。
- 脚本片段 :包含Java代码。
3.3 JavaBeans的使用
JavaBeans是一种可重用的Java组件,在JSP中可以方便地使用:
- 基本使用 :通过 jsp:useBean 标签创建和使用JavaBean。
- 属性关联 :可以将JavaBean的属性与输入参数关联,实现自动类型转换。
- 作用域 : jsp:useBean 的 scope 属性可以指定JavaBean的作用域,如 page 、 request 、 session 和 application 。
3.4 表单数据处理
表单数据是Web应用中常见的数据来源,处理步骤如下:
1. 定义表单 :使用HTML的 FORM 元素定义表单,指定 ACTION 和 METHOD 属性。
2. 读取数据 :在Servlet中使用 HttpServletRequest 的 getParameter 方法读取表单数据。
3. 处理数据 :根据业务逻辑处理读取到的数据。
3.5 请求转发和包含
在Web应用中,有时需要将请求转发到其他资源或包含其他资源的内容:
- 请求转发 :使用 RequestDispatcher 的 forward 方法将请求转发到另一个Servlet或JSP页面。
- 包含资源 :使用 RequestDispatcher 的 include 方法将其他资源的内容包含到当前页面。
3.6 自定义JSP标签库
自定义JSP标签库可以提高代码的复用性和可维护性,步骤如下:
1. 定义标签处理类 :实现 javax.servlet.jsp.tagext.Tag 接口或继承 javax.servlet.jsp.tagext.TagSupport 类。
2. 编写标签库描述文件(TLD) :定义标签的属性和行为。
3. 在JSP页面中引入标签库 :使用 taglib 指令引入自定义标签库。
3.7 数据库操作示例代码总结
以下是一个完整的JDBC数据库操作示例代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class DatabaseExample {
public static void main(String[] args) {
try {
// 加载驱动
Class.forName("oracle.jdbc.driver.OracleDriver");
// 定义连接URL
String host = "dbhost.yourcompany.com";
String dbName = "someName";
int port = 1234;
String oracleURL = "jdbc:oracle:thin:@" + host + ":" + port + ":" + dbName;
// 建立连接
String username = "jay_debesee";
String password = "secret";
Connection connection = DriverManager.getConnection(oracleURL, username, password);
// 创建语句对象
Statement statement = connection.createStatement();
// 执行查询
String query = "SELECT col1, col2, col3 FROM sometable";
ResultSet resultSet = statement.executeQuery(query);
// 处理结果
while (resultSet.next()) {
System.out.println(resultSet.getString(1) + " " +
resultSet.getString(2) + " " +
resultSet.getString(3));
}
// 关闭连接
resultSet.close();
statement.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
通过以上内容,我们全面了解了Servlet、JSP与数据库操作的相关技术,包括JDBC的基本使用、数据库连接池的实现、HTTP请求和响应头的处理、JSP指令和脚本元素的使用、JavaBeans的应用、表单数据处理、请求转发和包含以及自定义JSP标签库等。这些技术可以帮助我们开发出高效、稳定的Web应用程序。
4. 常见HTML表单元素及使用
HTML表单是Web应用中收集用户输入数据的重要方式,以下是常见的HTML表单元素及其使用方法:
4.1 文本控件
- 文本框(Textfields) :用于输入单行文本。
<input type="text" name="username" maxlength="50">
- 密码字段(Password fields) :用于输入密码,输入内容会被隐藏。
<input type="password" name="password" maxlength="20">
- 文本区域(Text areas) :用于输入多行文本。
<textarea name="message" cols="30" rows="5"></textarea>
4.2 按钮控件
- 提交按钮(Submit buttons) :用于提交表单数据。
<input type="submit" value="Submit">
- 重置按钮(Reset buttons) :用于重置表单中的所有输入。
<input type="reset" value="Reset">
- JavaScript按钮 :可以通过JavaScript实现自定义的交互效果。
<button onclick="myFunction()">Click me</button>
4.3 选择控件
- 单选按钮(Radio buttons) :用于从一组选项中选择一个。
<input type="radio" name="gender" value="male"> Male
<input type="radio" name="gender" value="female"> Female
- 复选框(Check boxes) :用于从一组选项中选择多个。
<input type="checkbox" name="hobbies" value="reading"> Reading
<input type="checkbox" name="hobbies" value="swimming"> Swimming
- 下拉框(Combo boxes) :提供一个下拉列表供用户选择。
<select name="country">
<option value="USA">USA</option>
<option value="China">China</option>
<option value="UK">UK</option>
</select>
4.4 文件上传控件
用于上传文件到服务器。
<input type="file" name="uploadFile" accept=".jpg,.png">
表单元素使用流程 mermaid 流程图
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始]):::startend --> B(创建表单):::process
B --> C(添加文本控件):::process
C --> D(添加按钮控件):::process
D --> E(添加选择控件):::process
E --> F(添加文件上传控件):::process
F --> G(设置表单属性):::process
G --> H(提交表单):::process
H --> I(服务器处理表单数据):::process
I --> J([结束]):::startend
5. 动态内容处理与数据传输
5.1 动态内容包含
在Web页面中,可以通过JSP的 include 指令或 jsp:include 标签在页面翻译时或请求时包含其他文件的内容。
- include指令 :在页面翻译时包含文件。
<%@ include file="header.jsp" %>
- jsp:include标签 :在请求时包含文件。
<jsp:include page="footer.jsp" />
5.2 数据传输
在Web应用中,数据传输主要通过HTTP协议进行,常见的请求方法有GET和POST:
- GET请求 :将数据附加在URL后面,适用于传输少量数据。
// 在Servlet中获取GET请求参数
String param = request.getParameter("paramName");
- POST请求 :将数据放在请求体中,适用于传输大量数据。
// 在Servlet中获取POST请求参数
BufferedReader reader = request.getReader();
String line;
StringBuilder requestBody = new StringBuilder();
while ((line = reader.readLine()) != null) {
requestBody.append(line);
}
5.3 HTTP状态码
HTTP状态码用于表示HTTP请求的结果,常见的状态码如下:
| 状态码 | 含义 |
| — | — |
| 200 | OK,表示请求成功。 |
| 404 | Not Found,表示请求的资源不存在。 |
| 500 | Internal Server Error,表示服务器内部错误。 |
动态内容处理与数据传输流程 mermaid 流程图
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始]):::startend --> B(用户发送请求):::process
B --> C{请求方法}:::decision
C -- GET --> D(将数据附加在URL后):::process
D --> E(服务器处理请求):::process
C -- POST --> F(将数据放在请求体中):::process
F --> E
E --> G{请求结果}:::decision
G -- 成功 --> H(返回200状态码和响应内容):::process
G -- 资源不存在 --> I(返回404状态码):::process
G -- 服务器错误 --> J(返回500状态码):::process
H --> K(用户接收响应):::process
I --> K
J --> K
K --> L([结束]):::startend
6. 综合应用示例
以下是一个综合应用示例,展示了如何使用上述技术开发一个简单的Web应用:
6.1 需求描述
开发一个简单的用户注册页面,用户可以输入用户名、密码和邮箱,提交表单后将数据保存到数据库中。
6.2 实现步骤
- 创建HTML表单页面(register.html)
<!DOCTYPE html>
<html>
<head>
<title>User Registration</title>
</head>
<body>
<form action="register.jsp" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username" required><br>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required><br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required><br>
<input type="submit" value="Register">
</form>
</body>
</html>
- 创建JSP页面(register.jsp)处理表单数据
<%@ page import="java.sql.*" %>
<%
String username = request.getParameter("username");
String password = request.getParameter("password");
String email = request.getParameter("email");
try {
// 加载驱动
Class.forName("oracle.jdbc.driver.OracleDriver");
// 定义连接URL
String host = "dbhost.yourcompany.com";
String dbName = "someName";
int port = 1234;
String oracleURL = "jdbc:oracle:thin:@" + host + ":" + port + ":" + dbName;
// 建立连接
String dbUsername = "jay_debesee";
String dbPassword = "secret";
Connection connection = DriverManager.getConnection(oracleURL, dbUsername, dbPassword);
// 创建预编译语句
String sql = "INSERT INTO users (username, password, email) VALUES (?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, username);
statement.setString(2, password);
statement.setString(3, email);
// 执行插入操作
statement.executeUpdate();
// 关闭连接
statement.close();
connection.close();
out.println("Registration successful!");
} catch (Exception e) {
e.printStackTrace();
out.println("Registration failed!");
}
%>
6.3 代码解释
-
register.html:创建一个包含用户名、密码和邮箱输入框的表单,表单提交到register.jsp页面。 -
register.jsp:接收表单数据,使用JDBC将数据插入到数据库中。如果插入成功,显示注册成功信息;否则,显示注册失败信息。
通过以上综合应用示例,我们可以看到如何将HTML表单、JSP、JDBC等技术结合起来开发一个简单的Web应用。在实际开发中,可以根据具体需求进行扩展和优化。
综上所述,掌握Servlet、JSP与数据库操作的相关技术,以及HTML表单元素的使用、动态内容处理和数据传输等知识,对于开发高效、稳定的Web应用程序至关重要。我们可以根据不同的业务需求,灵活运用这些技术,构建出功能丰富、用户体验良好的Web应用。
超级会员免费看
1771

被折叠的 条评论
为什么被折叠?



