12.2
在 JavaWeb 中实现单表的增删改查(CRUD)操作的一般步骤和示例代码,这里以 MySQL 数据库为例,并且使用 JDBC来连接数据库和执行操作。
- 准备工作
导入 JDBC 驱动包:确保在项目的依赖中添加了 MySQL 的 JDBC 驱动包(如mysql-connector-java),以便能够在 Java 程序中连接 MySQL 数据库。 - 建立数据库连接
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DatabaseConnection {
private static final String URL = "jdbc:mysql://localhost:3306/db1";
private static final String USERNAME = "root";
private static final String PASSWORD = "aaa666";
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USERNAME, PASSWORD);
}
}
3. 创建表对应的实体类
public class Student {
private int id;
private String name;
private int age;
public Student() {}
public Student(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
// 以下是各属性的getter和setter方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
4. 实现增删改查操作
插入数据(Create)
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class StudentDAO {
public void addStudent(Student student) {
try (Connection connection = DatabaseConnection.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO students (name, age) VALUES (?,?)")) {
preparedStatement.setString(1, student.getName());
preparedStatement.setInt(2, student.getAge());
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
在上述代码中,通过PreparedStatement来预编译 SQL 语句,然后设置参数并执行插入操作。
查询数据(Read)
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class StudentDAO {
public List
List
try (Connection connection = DatabaseConnection.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM students");
ResultSet resultSet = preparedStatement.executeQuery()) {
while (resultSet.next()) {
Student student = new Student();
student.setId(resultSet.getInt("id"));
student.setName(resultSet.getString("name"));
student.setAge(resultSet.getInt("age"));
students.add(student);
}
} catch (SQLException e) {
e.printStackTrace();
}
return students;
}
}
这里通过ResultSet来获取查询结果集,并将每行数据封装成Student对象添加到列表中。
修改数据(Update)
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class StudentDAO {
public void updateStudent(Student student) {
try (Connection connection = DatabaseConnection.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE students SET name =?, age =? WHERE id =?")) {
preparedStatement.setString(1, student.getName());
preparedStatement.setInt(2, student.getAge());
preparedStatement.setInt(3, student.getId());
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
同样使用PreparedStatement来预编译更新语句,设置相应参数后执行更新操作。
删除数据(Delete)
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class StudentDAO {
public void deleteStudent(int id) {
try (Connection connection = DatabaseConnection.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM students WHERE id =?")) {
preparedStatement.setInt(1, id);
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
通过PreparedStatement预编译删除语句,设置要删除记录的id参数后执行删除操作。
5. 测试操作
可以在main方法中编写如下测试代码:
public class Main {
public static void main(String[] args) {
// 测试插入操作
StudentDAO studentDAO = new StudentDAO();
Student newStudent = new Student(0, "John", 20);
studentDAO.addStudent(newStudent);
// 测试查询操作
List<Student> students = studentDAO.getAllStudents();
for (Student student : students) {
System.out.println("ID: " + student.getId() + ", Name: " + student.getName() + ", Age: " + student.getAge());
}
// 测试更新操作
Student toUpdateStudent = students.get(0);
toUpdateStudent.setName("Updated John");
studentDAO.updateStudent(toUpdateStudent);
// 测试删除操作
studentDAO.deleteStudent(toUpdateStudent.getId());
}
}
要实现通过页面来对数据库单表进行增删改查操作,通常需要结合前端页面(如 HTML、CSS、JavaScript)和后端代码(如 JavaWeb 相关技术)来完成。以下是一个较为基础的示例流程,以 Web 应用中常见的 JSP(JavaServer Pages)页面为例来说明如何实现与前面介绍的单表增删改查功能的交互:
- 前端页面设计
创建 HTML 页面(以index.html为例)
th,
td {
border: 1px solid black;
padding: 8px;
}
</style>
</head>
<body>
<h1>学生信息管理</h1>
<!-- 显示学生列表的表格 -->
<table id="studentTable">
<tr>
<th>ID</th>
<th>姓名</th>
<th>年龄</th>
<th>操作</th>
</tr>
</table>
<!-- 添加学生信息的表单 -->
<h2>添加学生</h2>
<form id="addStudentForm">
<label for="name">姓名:</label>
<input type="text" id="name" name="name" required><br>
<label for="age">年龄:</label>
<input type="number" id="age" name="age" required><br>
<input type="submit" value="添加学生">
</form>
<script src="script.js"></script>
</body>
在上述 HTML 页面中,定义了一个用于显示学生列表的表格和一个用于添加学生信息的表单。
创建 JavaScript 文件(script.js)
// 获取页面元素
const studentTable = document.getElementById('studentTable');
const addStudentForm = document.getElementById('addStudentForm');
// 函数:填充学生列表表格
function populateStudentTable(students) {
studentTable.innerHTML = ''; // 先清空表格内容
const tableHeader = document.createElement('tr');
const idHeader = document.createElement('th');
idHeader.textContent = 'ID';
const nameHeader = document.createElement('th');
nameHeader.textContent = '姓名';
const ageHeader = document.createElement('th');
ageHeader.textContent = '年龄';
const actionHeader = document.createElement('th');
actionHeader.textContent = '操作';
tableHeader.appendChild(idHeader);
tableHeader.appendChild(nameHeader);
tableHeader.appendChild(ageHeader);
tableHeader.appendChild(actionHeader);
studentTable.appendChild(tableHeader);
students.forEach((student) => {
const row = document.createElement('tr');
const idCell = document.createElement('td');
idCell.textContent = student.id;
const nameCell = document.createElement('td');
nameCell.textContent = student.name;
const ageCell = document.createElement('td');
ageCell.textContent = student.age;
const deleteButton = document.createElement('button');
deleteButton.textContent = '删除';
deleteButton.addEventListener('click', () => {
deleteStudent(student.id);
});
const updateButton = document.createElement('button');
updateButton.textContent = '更新';
updateButton.addEventListener('click', () => {
// 这里可以实现跳转到更新页面或者弹出更新表单等操作,暂不详细展开
console.log('更新学生:', student);
});
const actionCell = document.createElement('td');
actionCell.appendChild(deleteButton);
actionCell.appendChild(updateButton);
row.appendChild(idCell);
row.appendChild(nameCell);
row.appendChild(ageCell);
row.appendChild(actionCell);
studentTable.appendChild(row);
});
}
// 函数:添加学生
function addStudent() {
const name = document.getElementById('name').value;
const age = document.getElementById('age').value;
const studentData = {
name: name,
age: age
};
fetch('/addStudent', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(studentData)
})
.then(response => response.json())
.then(() => {
// 添加成功后重新获取学生列表并显示
getStudents();
})
.catch(error => console.error(error));
}
// 函数:删除学生
function deleteStudent(id) {
fetch('/deleteStudent/' + id, {
method: 'DELETE'
})
.then(response => response.json())
.then(() => {
// 删除成功后重新获取学生列表并显示
getStudents();
})
.catch(error => console.error(error));
}
// 函数:获取学生列表
function getStudents() {
fetch('/getStudents')
.then(response => response.json())
.then((students) => {
populateStudentTable(students);
})
.catch(error => console.error(error));
}
// 页面加载时获取学生列表并显示
window.onload = function () {
getStudents();
};
// 为添加学生表单添加提交事件监听器
addStudentForm.addEventListener('submit', (e) => {
e.preventDefault();
addStudent();
});
在上述 JavaScript 文件中,实现了以下几个主要功能:
填充学生列表表格:根据从后端获取的学生数据,动态生成表格内容并显示在页面上。
添加学生:获取表单输入的学生姓名和年龄信息,通过fetch API 发送POST请求到后端的/addStudent接口,添加成功后重新获取并显示学生列表。
删除学生:当点击删除按钮时,通过fetch API 发送DELETE请求到后端的/deleteStudent接口,删除成功后重新获取并显示学生列表。
获取学生列表:在页面加载时以及其他操作后需要重新获取学生列表时,通过fetch API 发送GET请求到后端的/getStudents接口,获取学生数据并调用填充表格函数进行显示。
2. 后端代码调整
在之前的 Java 代码基础上,需要进行一些调整来处理前端页面发送过来的请求并返回相应的结果。
修改StudentDAO类
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class StudentDAO {
// 获取所有学生信息
public List
List
try (Connection connection = DatabaseConnection.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM students")) {
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
Student student = new Student();
student.setId(resultSet.getInt("id"));
student.setName(resultSet.getString("id"));
student.setAge(resultSet.getInt("age"));
students.add(student);
}
} catch (SQLException e) {
e.printStackTrace();
}
return students;
}
// 根据ID获取单个学生信息
public Student getStudentById(int id) {
Student student = null;
try (Connection connection = DatabaseConnection.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM students WHERE id =?")) {
preparedStatement.setInt(1, id);
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
student = new Student();
student.setId(resultSet.getInt("id"));
student.setName(resultSet.getString("name"));
student.setAge(resultSet.getInt("age"));
}
} catch (SQLException e) {
e.printStackTrace();
}
return student;
}
// 添加学生信息
public void addStudent(Student student) {
try (Connection connection = DatabaseConnection.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO students (name, age) VALUES (?,?)")) {
preparedStatement.setString(1, student.getName());
preparedStatement.setInt(2, student.getAge());
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 更新学生信息
public void updateStudent(Student student) {
try (Connection connection = DatabaseConnection.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE students SET name =?, age =? WHERE id =?")) {
preparedStatement.setString(1, student.getName());
preparedStatement.setInt(2, if (student.getAge()!= null) {
return student.getAge();
} else {
return 0;
}));
preparedStatement.setInt(3, student.getId());
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 删除学生信息
public void deleteStudent(int id) {
try (Connection connection = DatabaseConnection.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM students WHERE id =?")) {
preparedStatement.setInt(1, id);
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
这里在StudentDAO类中增加了根据ID获取单个学生信息的方法。
创建 Servlet 类来处理前端请求
import com.google.gson.Gson;
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.util.List;
@WebServlet("/getStudents")
public class GetStudentsServlet extends HttpServlet {
@Override
protected void doGet() {
StudentDAO studentDAO = new StudentDAO();
List
Gson gson = new Gson();
String jsonResponse = gson.toJson(students);
try (PrintWriter writer = response.getWriter()) {
writer.write(jsonResponse);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@WebServlet("/addStudent")
public class AddStudentServlet extends HttpServlet {
@Override
protected void doPost() {
StudentDAO studentDAO = new StudentDAO();
Gson gson = new Gson();
try {
String requestBody = request.getReader().readString();
Student student = gson.fromJson(requestBody, Student.class);
studentDAO.addStudent(student);
try (PrintWriter writer = response.getWriter()) {
writer.write("添加成功");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
@WebServlet("/deleteStudent")
public class DeleteStudentServlet extends HttpServlet {
@Override
protected void doDelete() {
int id = Integer.parseInt(request.getPathInfo().substring(1));
StudentDAO studentDAO = new StudentDAO();
studentDAO.deleteStudent(id);
try (PrintWriter writer = response.getWriter()) {
writer.write("删除成功");
} catch (IOException e) {
e.printStackTrace();
}
}
}
@WebServlet("/updateStudent")
public class UpdateStudentServlet extends HttpServlet {
@Override
protected void doPut() {
StudentDAO studentDAO = new StudentDAO();
Gson gson = new Gson();
try {
String requestBody = request.getReader().readString();
Student student = gson.fromJson(requestBody, Student.class);
studentDAO.updateStudent(student);
try (PrintWriter writer = response.getWriter()) {
writer.write("更新成功");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上述代码中,创建了几个Servlet类来分别处理前端页面发送过来的GET(获取学生列表)、POST(添加学生)、DELETE(删除学生)、PUT(更新学生)等请求。通过Gson库将 Java 对象和 JSON 字符串进行相互转换,以便在前后端之间进行数据传输和交互。
在mysql中创建students表
CREATE TABLE students (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
age INT,
gender ENUM('男', '女', '其他') DEFAULT '其他',
major VARCHAR(255),
grade INT,
);
id:作为学生记录的唯一标识符,设置为自增长的整数类型,并将其指定为表的主键。这样每当插入一条新的学生记录时,id的值会自动递增。
name:用于存储学生的姓名,设置为VARCHAR类型,最大长度为 255 个字符,并且规定该字段不能为空,以确保每条学生记录都有对应的姓名信息。
age:用来记录学生的年龄,为整数类型。这里可以根据实际情况考虑是否设置年龄的取值范围限制等约束条件。
gender:表示学生的性别,采用ENUM枚举类型,列举了常见的性别选项 ' 男'、' 女 '、' 其他 ',并将默认值设置为 ' 其他 ',以便应对一些特殊情况。
major:存储学生所学的专业,也是VARCHAR类型,最大长度 255 个字符,可根据具体专业名称的长度需求进行调整。
grade:记录学生所在的年级,为整数类型。