42、Servlet、JSP与数据库操作的全面指南

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"); 
  1. 定义连接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;
  1. 建立连接
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();
  1. 创建语句对象
Statement statement = connection.createStatement();
  1. 执行查询或更新
String query = "SELECT col1, col2, col3 FROM sometable";
ResultSet resultSet = statement.executeQuery(query);
  1. 处理结果 :使用 next 方法获取新行,使用 getXxx(index) getXxx(columnName) 提取行中的值。第一列的索引是1,而不是0。
while(resultSet.next()) {
    System.out.println(resultSet.getString(1) + " " +
                       resultSet.getString(2) + " " +
                       resultSet.getString(3));
}
  1. 关闭连接
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);
  1. 指定查询参数 :使用 statement.setXxx 方法。
statement.setFloat(1, 1.234);
statement.setInt(2, 5);
  1. 执行操作
statement.execute();

2. 数据库连接池的实现步骤

数据库连接池可以提高数据库操作的性能,以下是实现连接池的步骤:
1. 预分配连接 :在类的构造函数中执行此任务,从Servlet的 init 方法调用构造函数。使用向量存储可用的空闲连接和不可用的繁忙连接。

availableConnections = new Vector(initialConnections);
busyConnections = new Vector();
for(int i = 0; i < initialConnections; i++) {
    availableConnections.addElement(makeNewConnection());
}
  1. 管理可用连接 :如果需要连接且有空闲连接可用,将其放入繁忙连接列表并返回。繁忙列表用于检查连接总数的限制,以及在需要显式关闭所有连接时使用。当丢弃一个连接时,使用 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;
        }
    }
}
  1. 分配新连接 :如果需要连接,没有空闲连接可用,且未达到连接限制,则启动一个后台线程分配新连接。然后等待第一个可用连接,无论是否是新分配的连接。
if ((totalConnections() < maxConnections) &&!connectionPending) {
    makeBackgroundConnection();
    try {
        wait();
    } catch(InterruptedException ie) {}
    return getConnection();
}
  1. 等待连接可用 :当没有空闲连接且达到连接数量限制时,使用 wait 方法等待,该方法会放弃线程同步锁并暂停线程,直到调用 notify notifyAll 方法。
try {
    wait();
} catch(InterruptedException ie) {}
return getConnection();
  1. 根据需要关闭连接 :虽然连接在垃圾回收时会关闭,但有时需要更明确地控制该过程。
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 实现步骤

  1. 创建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>
  1. 创建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应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值