手把手教你用JDBC搞定MySQL增删改查(附Educoder实战代码解析)
从零到精通的JDBC实战指南MySQL增删改查全解析在Java开发的世界里数据库操作是每个开发者必须掌握的技能。JDBC作为Java连接数据库的标准API虽然现在有各种ORM框架简化了操作但理解JDBC底层原理仍然是进阶高级开发的必经之路。本文将带你从零开始通过一个完整的员工管理系统案例深入理解JDBC的每一个关键步骤并教你如何将这些知识应用到实际项目中。1. JDBC基础与环境搭建1.1 JDBC核心组件解析JDBC(Java Database Connectivity)是Java语言中用来规范客户端程序如何访问数据库的应用程序接口。它主要由以下几个核心组件构成DriverManager负责管理数据库驱动建立与数据库的连接Connection表示与特定数据库的连接会话Statement/PreparedStatement用于执行静态SQL语句和预编译SQL语句ResultSet表示数据库结果集通常通过执行查询语句生成// JDBC基础使用流程示例 Class.forName(com.mysql.cj.jdbc.Driver); Connection conn DriverManager.getConnection(url, username, password); Statement stmt conn.createStatement(); ResultSet rs stmt.executeQuery(SELECT * FROM employee);1.2 MySQL环境准备在开始编码前我们需要准备好MySQL数据库环境。以下是推荐配置组件版本备注MySQL Server8.0社区版即可JDK11推荐LTS版本MySQL Connector/J8.0JDBC驱动安装完成后创建我们的示例数据库和表CREATE DATABASE tsgc CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE tsgc; CREATE TABLE employee ( no VARCHAR(10) PRIMARY KEY, name VARCHAR(50) NOT NULL, password VARCHAR(50), sex VARCHAR(10), salary DECIMAL(10,2) );2. 增删改查全流程实战2.1 数据库连接最佳实践建立数据库连接是JDBC操作的第一步也是容易出错的地方。以下是几个关键注意事项驱动加载现代JDBC驱动通常会自动注册但显式加载仍是好习惯连接字符串包含服务器地址、端口、数据库名和编码设置认证信息用户名和密码应通过安全方式管理连接池生产环境务必使用连接池(HikariCP等)public class DBUtil { private static final String URL jdbc:mysql://localhost:3306/tsgc?useSSLfalseserverTimezoneUTC; private static final String USER root; private static final String PASSWORD 123123; public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } }提示在生产环境中数据库连接信息应该放在配置文件中而不是硬编码在代码里。2.2 增删改查操作详解2.2.1 插入数据(INSERT)public void addEmployee(Employee emp) { String sql INSERT INTO employee(no, name, password, sex, salary) VALUES(?, ?, ?, ?, ?); try (Connection conn DBUtil.getConnection(); PreparedStatement pstmt conn.prepareStatement(sql)) { pstmt.setString(1, emp.getNo()); pstmt.setString(2, emp.getName()); pstmt.setString(3, emp.getPassword()); pstmt.setString(4, emp.getSex()); pstmt.setDouble(5, emp.getSalary()); pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } }2.2.2 查询数据(SELECT)public ListEmployee getAllEmployees() { ListEmployee employees new ArrayList(); String sql SELECT * FROM employee; try (Connection conn DBUtil.getConnection(); Statement stmt conn.createStatement(); ResultSet rs stmt.executeQuery(sql)) { while (rs.next()) { Employee emp new Employee(); emp.setNo(rs.getString(no)); emp.setName(rs.getString(name)); emp.setPassword(rs.getString(password)); emp.setSex(rs.getString(sex)); emp.setSalary(rs.getDouble(salary)); employees.add(emp); } } catch (SQLException e) { e.printStackTrace(); } return employees; }3. 高级技巧与性能优化3.1 PreparedStatement的优势与Statement相比PreparedStatement有三大优势防止SQL注入通过参数化查询避免拼接SQL字符串性能更好SQL语句预编译多次执行只需编译一次可读性高参数通过set方法设置代码更清晰// 使用PreparedStatement更新数据 public void updatePassword(String no, String newPassword) { String sql UPDATE employee SET password ? WHERE no ?; try (Connection conn DBUtil.getConnection(); PreparedStatement pstmt conn.prepareStatement(sql)) { pstmt.setString(1, newPassword); pstmt.setString(2, no); int affectedRows pstmt.executeUpdate(); System.out.println(更新了 affectedRows 条记录); } catch (SQLException e) { e.printStackTrace(); } }3.2 事务处理机制JDBC默认是自动提交模式要使用事务需要手动控制public void transferSalary(String fromNo, String toNo, double amount) { Connection conn null; try { conn DBUtil.getConnection(); conn.setAutoCommit(false); // 开始事务 // 扣除转出员工工资 String sql1 UPDATE employee SET salary salary - ? WHERE no ?; try (PreparedStatement pstmt1 conn.prepareStatement(sql1)) { pstmt1.setDouble(1, amount); pstmt1.setString(2, fromNo); pstmt1.executeUpdate(); } // 增加转入员工工资 String sql2 UPDATE employee SET salary salary ? WHERE no ?; try (PreparedStatement pstmt2 conn.prepareStatement(sql2)) { pstmt2.setDouble(1, amount); pstmt2.setString(2, toNo); pstmt2.executeUpdate(); } conn.commit(); // 提交事务 } catch (SQLException e) { if (conn ! null) { try { conn.rollback(); // 回滚事务 } catch (SQLException ex) { ex.printStackTrace(); } } e.printStackTrace(); } finally { if (conn ! null) { try { conn.setAutoCommit(true); // 恢复自动提交 conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }4. 项目实战员工管理系统4.1 系统架构设计一个完整的员工管理系统应该包含以下模块数据访问层(DAO)封装所有数据库操作业务逻辑层(Service)处理业务规则和流程表现层用户界面或API接口src/ ├── main/ │ ├── java/ │ │ ├── dao/ │ │ │ └── EmployeeDao.java │ │ ├── service/ │ │ │ └── EmployeeService.java │ │ ├── model/ │ │ │ └── Employee.java │ │ └── util/ │ │ └── DBUtil.java │ └── resources/ │ └── db.properties └── test/ └── java/ └── dao/ └── EmployeeDaoTest.java4.2 异常处理与日志记录良好的异常处理和日志记录是健壮系统的关键public class EmployeeDao { private static final Logger logger Logger.getLogger(EmployeeDao.class.getName()); public boolean deleteEmployee(String no) { String sql DELETE FROM employee WHERE no ?; try (Connection conn DBUtil.getConnection(); PreparedStatement pstmt conn.prepareStatement(sql)) { pstmt.setString(1, no); int affectedRows pstmt.executeUpdate(); return affectedRows 0; } catch (SQLException e) { logger.log(Level.SEVERE, 删除员工失败: no, e); throw new RuntimeException(数据库操作失败, e); } } }在实际项目中我发现将JDBC操作封装到DAO层后业务代码会变得非常简洁。例如查询高薪员工只需要调用employeeDao.findBySalaryGreaterThan(threshold)而不需要关心具体的SQL和ResultSet处理。