[MySQL]表——改变数据
文章目录
- 一、引言:数据更新在应用中的重要性
- 二、环境准备与数据初始化
- 2.1 数据库表结构
- 2.2 项目依赖配置
- 三、完整代码解析
- 四、四种更新方式详解
- 4.1 基本更新:单字段精确更新
- 4.2 安全更新:多字段完整更新
- 4.3 条件更新:批量智能更新
- 4.4 动态更新:灵活智能更新
一、引言:数据更新在应用中的重要性
在真实的企业级应用中,数据更新操作占据了数据库操作的很大比重。无论是用户修改个人信息、管理员调整系统配置,还是系统自动更新状态,都需要用到UPDATE操作。掌握高效、安全的数据更新技术,对于Java开发者来说至关重要。
本文将基于一个完整的学生信息管理系统示例,演示四种不同类型的更新操作,每种操作都有其特定的应用场景和优势。
主要关键字:
修改数据
UPDATE 表名 SET 字段名1 = 值1, 字段名2 = 值2, ... [ WHERE 条件]
二、环境准备与数据初始化
2.1 数据库表结构
在开始编码前,我们需要准备测试数据。创建以下MySQL表结构:
CREATE DATABASE IF NOT EXISTS user;
USE user;CREATE TABLE students (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL,age INT NOT NULL,email VARCHAR(100)
);INSERT INTO students (name, age, email) VALUES
('张三', 20, 'zhangsan@email.com'),
('李四', 22, 'lisi@email.com'),
('王五', 19, 'wangwu@email.com'),
('赵六', 21, 'zhaoliu@email.com');
2.2 项目依赖配置
如果使用Maven,请在pom.xml中添加MySQL驱动依赖:
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version>
</dependency>
三、完整代码解析
下面是我们将要详细讲解的完整代码,它展示了四种不同的更新操作方式:
package org.example;import java.sql.*;
import java.util.ArrayList;
import java.util.List;/*** 完整的JDBC数据更新实战示例*/
public class ComprehensiveUpdateDemo {private static final String URL = "jdbc:mysql://127.0.0.1:3306/user?useSSL=false&serverTimezone=UTC";private static final String USERNAME = "root";private static final String PASSWORD = "123456";public static void main(String[] args) {// 显示更新前的数据System.out.println("=== 更新前的数据 ===");displayAllStudents();// 执行各种更新操作System.out.println("\n=== 执行更新操作 ===");// 1. 基本更新basicUpdateStudent(1, 22);// 2. 安全更新(多字段)safeUpdateStudent(2, "李四新", 23, "lisi_new@email.com");// 3. 条件更新updateStudentsByCondition();// 4. 动态更新dynamicUpdateStudent(3, null, 26, "wangwu_updated@email.com");// 显示更新后的数据System.out.println("\n=== 更新后的数据 ===");displayAllStudents();}/*** 基本更新:只更新年龄*/public static void basicUpdateStudent(int id, int newAge) {String sql = "UPDATE students SET age = ? WHERE id = ?";try (Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);PreparedStatement pstmt = conn.prepareStatement(sql)) {pstmt.setInt(1, newAge);pstmt.setInt(2, id);int affectedRows = pstmt.executeUpdate();if (affectedRows > 0) {System.out.println("✅ 已更新ID " + id + " 的年龄为: " + newAge);}} catch (SQLException e) {System.err.println("基本更新失败: " + e.getMessage());}}/*** 安全更新多个字段*/public static void safeUpdateStudent(int id, String name, int age, String email) {String sql = "UPDATE students SET name = ?, age = ?, email = ? WHERE id = ?";try (Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);PreparedStatement pstmt = conn.prepareStatement(sql)) {pstmt.setString(1, name);pstmt.setInt(2, age);pstmt.setString(3, email);pstmt.setInt(4, id);int affectedRows = pstmt.executeUpdate();if (affectedRows > 0) {System.out.println("✅ 已更新ID " + id + " 的完整信息");}} catch (SQLException e) {System.err.println("安全更新失败: " + e.getMessage());}}/*** 根据条件更新多条记录*/public static void updateStudentsByCondition() {String sql = "UPDATE students SET age = age + 1 WHERE age < 22";try (Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);Statement stmt = conn.createStatement()) {int affectedRows = stmt.executeUpdate(sql);System.out.println("✅ 已为 " + affectedRows + " 名年龄小于22的学生增加1岁");} catch (SQLException e) {System.err.println("条件更新失败: " + e.getMessage());}}/*** 动态更新(只更新非空字段)*/public static void dynamicUpdateStudent(int id, String name, Integer age, String email) {StringBuilder sql = new StringBuilder("UPDATE students SET ");List<Object> params = new ArrayList<>();if (name != null) {sql.append("name = ?, ");params.add(name);}if (age != null) {sql.append("age = ?, ");params.add(age);}if (email != null) {sql.append("email = ?, ");params.add(email);}// 检查是否有字段需要更新if (params.isEmpty()) {System.out.println("⚠️ 没有提供任何更新字段");return;}// 移除最后的", "并添加WHERE条件sql.setLength(sql.length() - 2);sql.append(" WHERE id = ?");params.add(id);try (Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);PreparedStatement pstmt = conn.prepareStatement(sql.toString())) {for (int i = 0; i < params.size(); i++) {pstmt.setObject(i + 1, params.get(i));}int affectedRows = pstmt.executeUpdate();if (affectedRows > 0) {System.out.println("✅ 动态更新ID " + id + " 成功");}} catch (SQLException e) {System.err.println("动态更新失败: " + e.getMessage());}}/*** 显示所有学生记录*/public static void displayAllStudents() {String sql = "SELECT id, name, age, email FROM students ORDER BY id";try (Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(sql)) {System.out.println("ID\t姓名\t\t年龄\t邮箱");System.out.println("----------------------------------------------");while (rs.next()) {System.out.printf("%d\t%-8s\t%d\t%s%n",rs.getInt("id"),rs.getString("name"),rs.getInt("age"),rs.getString("email"));}} catch (SQLException e) {System.err.println("查询失败: " + e.getMessage());}}
}
四、四种更新方式详解
4.1 基本更新:单字段精确更新
/*** 基本更新:只更新年龄* 适用场景:只需要修改单个字段的简单操作*/
public static void basicUpdateStudent(int id, int newAge) {String sql = "UPDATE students SET age = ? WHERE id = ?";try (Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);PreparedStatement pstmt = conn.prepareStatement(sql)) {pstmt.setInt(1, newAge);pstmt.setInt(2, id);int affectedRows = pstmt.executeUpdate();if (affectedRows > 0) {System.out.println("✅ 已更新ID " + id + " 的年龄为: " + newAge);}} catch (SQLException e) {System.err.println("基本更新失败: " + e.getMessage());}
}
技术要点:
- 使用PreparedStatement防止SQL注入
- 参数化查询确保类型安全
- executeUpdate()返回受影响的行数
- try-with-resources自动管理资源
4.2 安全更新:多字段完整更新
/*** 安全更新多个字段* 适用场景:需要同时更新多个相关字段*/
public static void safeUpdateStudent(int id, String name, int age, String email) {String sql = "UPDATE students SET name = ?, age = ?, email = ? WHERE id = ?";try (Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);PreparedStatement pstmt = conn.prepareStatement(sql)) {pstmt.setString(1, name);pstmt.setInt(2, age);pstmt.setString(3, email);pstmt.setInt(4, id);int affectedRows = pstmt.executeUpdate();if (affectedRows > 0) {System.out.println("✅ 已更新ID " + id + " 的完整信息");}} catch (SQLException e) {System.err.println("安全更新失败: " + e.getMessage());}
}
技术要点:
- 一次性更新多个相关字段
- 保持数据的一致性
- 适用于完整记录更新的场景
4.3 条件更新:批量智能更新
/*** 根据条件更新多条记录* 适用场景:需要基于特定条件批量更新数据*/
public static void updateStudentsByCondition() {String sql = "UPDATE students SET age = age + 1 WHERE age < 22";try (Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);Statement stmt = conn.createStatement()) {int affectedRows = stmt.executeUpdate(sql);System.out.println("✅ 已为 " + affectedRows + " 名年龄小于22的学生增加1岁");} catch (SQLException e) {System.err.println("条件更新失败: " + e.getMessage());}
}
技术要点:
-
使用Statement因为不涉及用户输入参数
-
基于条件批量更新,提高效率
-
适用于系统自动维护任务
4.4 动态更新:灵活智能更新
/*** 动态更新(只更新非空字段)* 适用场景:前端只传递了部分修改字段,其他字段保持不变*/
public static void dynamicUpdateStudent(int id, String name, Integer age, String email) {StringBuilder sql = new StringBuilder("UPDATE students SET ");List<Object> params = new ArrayList<>();if (name != null) {sql.append("name = ?, ");params.add(name);}if (age != null) {sql.append("age = ?, ");params.add(age);}if (email != null) {sql.append("email = ?, ");params.add(email);}// 检查是否有字段需要更新if (params.isEmpty()) {System.out.println("⚠️ 没有提供任何更新字段");return;}// 移除最后的", "并添加WHERE条件sql.setLength(sql.length() - 2);sql.append(" WHERE id = ?");params.add(id);try (Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);PreparedStatement pstmt = conn.prepareStatement(sql.toString())) {for (int i = 0; i < params.size(); i++) {pstmt.setObject(i + 1, params.get(i));}int affectedRows = pstmt.executeUpdate();if (affectedRows > 0) {System.out.println("✅ 动态更新ID " + id + " 成功");}} catch (SQLException e) {System.err.println("动态更新失败: " + e.getMessage());}
}
技术要点:
- 动态构建SQL语句,只更新非空字段
- 使用StringBuilder高效拼接SQL
- List管理动态参数
- 适用于部分更新的场景
