首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

JDBC 操作 MySQL 實戰 (四):員工信息增刪改查與實體類映射封裝

     編輯:MySQL 綜合教學

JDBC 操作 MySQL 實戰 (四):員工信息增刪改查與實體類映射封裝

本文延續 JDBC 系列,通過完整的 Emp 實體類與 EmpDAO 數據訪問對象,演示 INSERT 新增員工、UPDATE 修改薪資的標準流程,重點講解參數封裝、SQL 拼接風險、事務邊界與資源關閉模式。

領域模型:Emp 實體類

遵循 JavaBean 規範:私有字段 + 公共 Getter/Setter + 無參構造器 + 全參構造器,實現數據庫表列與對象屬性一對一映射。

public class Emp {
    private int empNo;
    private String ename;
    private String job;
    private int mgr;
    private String hiredate; // 建議用 LocalDate (Java 8+) 或 Date
    private double sal;
    private double comm;
    private int deptno;
    // ... Getter/Setter/Constructors 省略
}

設計原則:將表字段封裝為對象屬性,避免方法參數列表過長 (8 字段 → 1 個對象),提高可讀性與擴展性。

DAO 模式:EmpDAO 核心方法

1. 新增員工 (add)

public void add(Emp emp) {
    String sql = "INSERT INTO emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) " +
                 "VALUES (?, ?, ?, ?, STR_TO_DATE(?, '%Y-%m-%d'), ?, ?, ?)";
    // 使用 PreparedStatement 防注入,佔位符對應 setter
    try (Connection con = ConnectionSource.getConnection();
         PreparedStatement ps = con.prepareStatement(sql)) {
        ps.setInt(1, emp.getEmpNo());
        ps.setString(2, emp.getEname());
        ps.setString(3, emp.getJob());
        ps.setInt(4, emp.getMgr());
        ps.setString(5, emp.getHiredate()); // 格式 yyyy-MM-dd
        ps.setDouble(6, emp.getSal());
        ps.setDouble(7, emp.getComm());
        ps.setInt(8, emp.getDeptno());
        int rows = ps.executeUpdate();
        if (rows > 0) System.out.println("新增記錄成功!ID: " + emp.getEmpNo());
    } catch (SQLException e) {
        throw new RuntimeException("數據庫訪問異常", e);
    }
}

關鍵點:

  • 使用 PreparedStatement 而非字符串拼接,徹底防止 SQL 注入。
  • 日期轉換:MySQL STR_TO_DATE(?, '%Y-%m-%d') 處理字符串日期。
  • Try-with-resources (Java 7+) 自動關閉資源,無需手寫 finally。

2. 更新薪資 (update)

public void update(Emp emp) {
    String sql = "UPDATE emp SET sal = ?, comm = ? WHERE empno = ?";
    try (Connection con = ConnectionSource.getConnection();
         PreparedStatement ps = con.prepareStatement(sql)) {
        ps.setDouble(1, emp.getSal());
        ps.setDouble(2, emp.getComm());
        ps.setInt(3, emp.getEmpNo());
        int rows = ps.executeUpdate();
        if (rows > 0) System.out.println("更新記錄成功!ID: " + emp.getEmpNo());
    } catch (SQLException e) {
        throw new RuntimeException("數據庫訪問異常", e);
    }
}

測試驗證

public static void main(String[] args) {
    EmpDAO dao = new EmpDAO();
    // 1. 查詢所有
    dao.findAll();
    // 2. 新增
    Emp emp = new Emp(1001, "rose", "Analyst", 7901, "2014-05-01", 3000.00, 500.00, 10);
    dao.add(emp);
    // 3. 更新薪資
    emp.setSal(4500.00);
    dao.update(emp);
}

控制台輸出確認新增與更新成功,數據庫表數據同步變更。

常見坑點與修正

  • 主鍵衝突:重複運行測試導致 Duplicate entry '1001' for key 'PRIMARY'。解決:測試前清理數據、使用自增主鍵、或捕獲異常處理。
  • 日期格式:字符串日期必須與 STR_TO_DATE 格式字符串完全匹配。
  • SQL 拼接風險:原文使用字符串拼接 \"... VALUES (\" + emp.getEmpNo() + \", ...\" 極易注入,**生產代碼禁止使用**。

進階延伸

  • 引入連接池 (HikariCP/Druid) 替換 ConnectionSource。
  • 使用 MyBatis/JPA 等 ORM 框架消除樣板代碼。
  • 事務控制上移至 Service 層,DAO 單純負責單條 SQL 執行。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved