1、 实验目的
掌握JDBC常用接口的使用,包括Driver接口、DriverManager类、Statement接口、PreparedStatement接口和ResultSet接口。掌握并实现JDBC程序的全过程。学习和掌握使用JDBC连接数据库,并完成对数据的增删改查。学习和掌握使用JDBC查询数据库对用户的用户名和密码进行检验,实现用户登录功能。
2、 实验所用方法
上机实践
3、 实验步骤及截图
创建一个数据库表,使用下面sql语句在MySQLworkbench插入数据。创建的名称为jdbc的数据库,然后在该数据库中创建一个tb_user表,并在tb_user表插入一条用户数据:
sql
CREATE TABLE tb_user (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,-- id主键
username VARCHAR(40) NOT NULL,-- 账户名称,设置不为空
PASSWORD VARCHAR(40) NOT NULL,-- 密码,设置不为空
NAME VARCHAR(40) DEFAULT NULL,-- 用户真实姓名,默认为空
gender VARCHAR(20) DEFAULT NULL,-- 用户性别,默认为空
phonenumber VARCHAR(30) DEFAULT NULL, -- 用户手机号码,默认为空
identitycode VARCHAR(30) DEFAULT NULL-- 用户身份证号码,默认为空
);
INSERT INTO tb_user VALUES(1,'张三','123','张三','male','13888888888','110202107075023');

在web目录下创建一个名称为login的JSP文件,在该文件中添加用于用户登录时输入用户信息的表单元素:
javascript
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录页面</title>
</head>
<style>
* {
margin: 0;
padding: 0;
}
form {
display: block;
height: auto;
width: 450px;
margin: 100px auto;
}
form table tr {
height: 40px;
}
form table tr td {
height: 40px;
width: 280px;
line-height: 40px;
}
form table tr td input {
height: 32px;
border: 1px solid #BABABA;
border-radius: 6px;
}
.alignRight {
text-align: right;
line-height: 40px;
font-size: 16px;
font-family: "Monaco";
width: 200px;
}
.submit {
display: block;
height: 40px;
width: 250px;
color: white;
font-weight: bold;
font-size: 18px;
background-color: #98ECAC;
border-radius: 8px;
margin: 15px auto;
}
</style>
<body>
<form action="LoginServlet" method="post">
<table>
<tr>
<td class="alignRight">
Username:
</td>
<td>
<input type="text" name="username" />
</td>
</tr>
<tr>
<td class="alignRight">
Password:
</td>
<td>
<input type="password" name="password" />
</td>
</tr>
</table>
<input type="submit" value="登 录" class="submit" />
</form>
</body>
</html>

由于每次操作数据库时,都需要加载数据库驱动、建立数据库连接以及关闭数据库连接,为了避免代码的重复书写,下面建立一个专门用于操作数据库的工具类。在src目录的cn.itcast包下创建一个GetConnection工具类:
javascript
package cn.itcast;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class GetConnection {
Connection conn = null;
public Connection getConnection() throws ClassNotFoundException {
String driver="com.mysql.cj.jdbc.Driver"; //驱动路径
String url= "jdbc:mysql://localhost:3306/jdbc?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8"; //数据库地址
String user="root"; //访问数据库的用户名
String password="root"; //用户自己的密码
Class.forName(driver);
try {
conn = DriverManager.getConnection(url,user,password);
} catch (SQLException e) {
e.printStackTrace();
}
//返回Connection对象
return conn;
}
}

在项目src目录的cn.itcast包下创建LoginServlet类,用于封装用户的登录信息并对用户信息进行校验:
javascript
package cn.itcast;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
@WebServlet(name = "LoginServlet",urlPatterns = "/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse
response)throws ServletException, IOException {
//设置请求编码、响应方式和编码方式
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
Connection conn = null;
Statement st = null;
ResultSet rs = null;
PreparedStatement ptst = null;
//获取登录页面提交的数据
String loginName = request.getParameter("username");
String loginPassword = request.getParameter("password");
//sql语句
String selectUsername = "select username from tb_user";
String selectPassword = "select password from tb_user where username = ?";
try {
//获取与数据库的链接
conn = new GetConnection().getConnection();
//遍历tb_user表,将数据库中所有username存入集合中
st = conn.createStatement();
rs = st.executeQuery(selectUsername);
List<String> usernameList = new ArrayList<String>();
while (rs.next()) {
usernameList.add(rs.getString(1));
}
//关闭连接
if (rs != null) {
rs.close();
}
if (st != null) {
st.close();
}
//判断集合中是否存在所要登录的username
if (usernameList.contains(loginName)) {
//查找username对应的password
List<String> passwordList = new ArrayList<String>();
ptst = (PreparedStatement)
conn.prepareStatement(selectPassword);
//设置ptst参数
ptst.setString(1, loginName);
rs = ptst.executeQuery();
while (rs.next()) {
passwordList.add(rs.getString(1));
}
//判断数据库与登录页面提交的password是否一致
if (passwordList.get(0).equals(loginPassword)) {
out.println("欢迎登录。");
} else {
out.println("密码错误,请重新输入。");
}
if (rs != null) {
rs.close();
}
if (ptst != null) {
ptst.close();
}
} else {
out.println("用户名不存在");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
//关闭链接
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
out.flush();
out.close();
}
}

登录网页:


4、 实验过程中出现的问题
login.jsp页面后跳转LoginServlet验证,jsp里的action路径写错了会报404的错。
5、 实验心得
通过本次实验深刻体会到JDBC在Java应用程序与数据库交互中的重要作用。
掌握了JDBC的核心接口和类后,我能够更加高效地编写数据库操作代码。也更加巩固了课堂知识:Driver接口是JDBC驱动程序的接口,每个JDBC驱动程序都必须实现该接口。尽管我们一般不会直接使用Driver接口,但了解其存在对于理解JDBC架构很重要。而DriverManager类管理一组JDBC驱动程序的基本服务。它用于建立与数据库的连接,通常通过调用DriverManager.getConnection()方法实现。Statement接口用于执行静态SQL语句并返回它所生成结果的对象。通过调用createStatement()方法从Connection对象获取。PreparedStatement接口是Statement的子接口,代表预编译的SQL语句。它主要用于执行带有参数的SQL语句,以提高安全性和性能。ResultSet接口表示数据库结果集的数据表,通过它可以前向遍历查询结果。特别是在实现用户登录功能时,深刻理解了PreparedStatement的重要性,它不仅提高了代码的安全性,还简化了SQL语句的编写过程。
在实验的过程中我也意识到了资源管理的重要性。在JDBC编程中,正确地关闭资源(如ResultSet、Statement和Connection)是防止资源泄漏的关键。通过养成在finally块中关闭资源的习惯,这样做能够确保即使在发生异常的情况下,资源也能被正确释放。