上一篇
servlet怎么和数据库链接
- 数据库
- 2025-07-24
- 4
要实现Servlet与数据库的链接,需先配置JDBC驱动(如添加mysql-connector-java.jar),通过
Class.forName()
加载驱动,再利用
DriverManager.getConnection()
获取连接对象,最后通过Statement或PreparedStatement执行SQL操作,注意及时关闭连接
以下是关于Servlet如何与数据库链接的详细解答:
环境准备
-
开发工具与环境
- JDK:需安装Java Development Kit(建议版本≥1.8)。
- Servlet容器:如Apache Tomcat、Jetty等。
- 数据库:如MySQL、PostgreSQL、Oracle等。
- 数据库驱动:根据数据库类型选择对应的JDBC驱动(如MySQL的
mysql-connector-java
)。
-
配置库依赖
将数据库驱动的JAR文件放入Servlet项目的WEB-INF/lib
目录,或通过Maven/Gradle添加依赖。<!-Maven依赖示例(MySQL) --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency>
Servlet与数据库链接的步骤
步骤 | 操作说明 | 代码示例 |
---|---|---|
加载驱动 | 通过Class.forName() 加载数据库驱动类 |
“`java |
// 加载MySQL驱动
Class.forName(“com.mysql.cj.jdbc.Driver”);
| 2. 建立连接 | 使用`DriverManager.getConnection()`获取数据库连接 | ```java
// 数据库URL格式:jdbc:subprotocol://ip:port/database
String url = "jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC";
Connection conn = DriverManager.getConnection(url, "username", "password");
``` |
| 3. 创建Statement | 通过`Connection.prepareStatement()`创建预编译语句 | ```java
String sql = "SELECT FROM users WHERE id = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, 1001); // 设置参数
``` |
| 4. 执行查询 | 调用`executeQuery()`执行SQL并返回结果集 | ```java
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
out.println("用户名:" + rs.getString("username"));
}
``` |
| 5. 处理结果 | 遍历`ResultSet`提取数据 | 同上代码 |
| 6. 释放资源 | 关闭`ResultSet`→`Statement`→`Connection` | ```java
rs.close();
pstmt.close();
conn.close();
``` |
三、完整代码示例(Servlet)
```java
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.;
public class DatabaseServlet extends HttpServlet {
private static final String DB_URL = "jdbc:mysql://localhost:3306/testdb";
private static final String DB_USER = "root";
private static final String DB_PASSWORD = "123456";
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置响应格式
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
// 1. 加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 建立连接
conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
// 3. 创建SQL语句
String sql = "SELECT id, username, email FROM users";
pstmt = conn.prepareStatement(sql);
// 4. 执行查询
rs = pstmt.executeQuery();
// 5. 输出结果
out.println("<table border='1'><tr><th>ID</th><th>用户名</th><th>邮箱</th></tr>");
while (rs.next()) {
out.println("<tr><td>" + rs.getInt("id") + "</td><td>" + rs.getString("username") + "</td><td>" + rs.getString("email") + "</td></tr>");
}
out.println("</table>");
} catch (ClassNotFoundException e) {
out.println("驱动加载失败:" + e.getMessage());
} catch (SQLException e) {
out.println("数据库错误:" + e.getMessage());
} finally {
// 6. 释放资源
try { if (rs != null) rs.close(); } catch (SQLException ignored) {}
try { if (pstmt != null) pstmt.close(); } catch (SQLException ignored) {}
try { if (conn != null) conn.close(); } catch (SQLException ignored) {}
}
}
}
常见问题与解决方案
驱动加载失败(ClassNotFoundException
)
原因:未正确引入数据库驱动JAR包,或驱动类名错误。
解决:
- 确认驱动JAR已放入
WEB-INF/lib
或通过构建工具添加依赖。 - 检查驱动类名是否正确(如MySQL为
com.mysql.cj.jdbc.Driver
)。
数据库连接泄漏
原因:未关闭Connection
或Statement
对象。
解决:
- 在
finally
块中关闭资源,或使用try-with-resources
语法(JDK 7+):try (Connection conn = DriverManager.getConnection(...); PreparedStatement pstmt = conn.prepareStatement(...); ResultSet rs = pstmt.executeQuery()) { // 处理逻辑 } catch (SQLException e) { // 异常处理 }
最佳实践
- 使用连接池:在实际项目中,直接使用
DriverManager
效率较低,推荐使用连接池(如HikariCP、Druid)提升性能。 - 参数化查询:始终使用
PreparedStatement
代替Statement
,防止SQL注入攻击。 - 异常处理:记录日志(如使用Log4j、SLF4J)而非直接输出错误信息。
- 分离逻辑:将数据库操作封装到DAO(Data Access Object)层,保持Servlet简洁。
相关问答FAQs
Q1:如何更换数据库类型(如从MySQL改为PostgreSQL)?
A1:只需替换以下内容:
- 驱动类名:
org.postgresql.Driver
- 数据库URL:
jdbc:postgresql://localhost:5432/testdb
- 驱动依赖:引入PostgreSQL的JDBC驱动JAR(如
postgresql-42.6.0.jar
)。
代码中其他部分(如Connection
、PreparedStatement
)无需修改。
Q2:为什么推荐使用PreparedStatement
而不是Statement
?
A2:
- 安全性:
PreparedStatement
支持参数化查询,可防止SQL注入攻击。 - 性能:数据库可预编译SQL语句,提升执行效率(尤其适用于多次执行相同语句)。
- 灵活性:支持动态参数绑定