基於 Oracle 資料庫,展示標準 JDBC 操作、PreparedStatement 防注入、資源管理、分頁查詢 (存儲過程) 等企業級開發常用模式。
public class EmpDaoImpl implements EmpDao {
// 新增
@Override public boolean insert(Emp emp) {
String sql = "INSERT INTO emp VALUES (?,?,?,?,?,?,?,?)";
try (Connection conn = DBConnection.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, emp.getEmpno());
ps.setString(2, emp.getEname());
ps.setString(3, emp.getJob());
if (emp.getMgr() == 0) ps.setNull(4, Types.INTEGER);
else ps.setInt(4, emp.getMgr());
ps.setDate(5, new java.sql.Date(emp.getHiredate().getTime()));
ps.setDouble(6, emp.getSal());
ps.setDouble(7, emp.getComm());
ps.setInt(8, emp.getDeptno());
return ps.executeUpdate() > 0;
} catch (SQLException e) { e.printStackTrace(); return false; }
}
// 刪除 (依條件)
@Override public boolean delete(String condition) {
String sql = "DELETE FROM emp WHERE " + condition;
try (Connection conn = DBConnection.getConnection();
Statement stmt = conn.createStatement()) {
return stmt.executeUpdate(sql) > 0;
} catch (SQLException e) { e.printStackTrace(); return false; }
}
// 刪除全部
@Override public boolean deleteAll() {
return DBConnection.executeUpdate("DELETE FROM emp", null) > 0;
}
// 查詢全部
@Override public Vector<Emp> queryAll() {
Vector<Emp> list = new Vector<>();
String sql = "SELECT empno,ename,job,mgr,hiredate,sal,comm,deptno FROM emp";
try (Connection conn = DBConnection.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
Emp e = new Emp();
e.setEmpno(rs.getInt("empno"));
e.setEname(rs.getString("ename"));
e.setJob(rs.getString("job"));
e.setMgr(rs.getInt("mgr"));
e.setHiredate(rs.getDate("hiredate"));
e.setSal(rs.getDouble("sal"));
e.setComm(rs.getDouble("comm"));
e.setDeptno(rs.getInt("deptno"));
list.add(e);
}
} catch (SQLException e) { e.printStackTrace(); }
return list;
}
// 分頁查詢 (調用 Oracle 存儲過程)
@Override public Vector<Emp> queryByPage(int pageNum) {
Vector<Emp> list = new Vector<>();
String sql = "{call data_control.pagedata('SCOTT.EMP',?,?,?)}";
try (Connection conn = DBConnection.getConnection();
CallableStatement cs = conn.prepareCall(sql)) {
cs.setInt(1, pageNum);
cs.setInt(2, Integer.parseInt(DBConfigUtil.getProperty("page.default.count")));
cs.registerOutParameter(3, OracleTypes.CURSOR);
cs.execute();
try (ResultSet rs = (ResultSet) cs.getObject(3)) {
while (rs.next()) {
Emp e = new Emp();
e.setEmpno(rs.getInt("empno"));
e.setEname(rs.getString("ename"));
e.setJob(rs.getString("job"));
e.setMgr(rs.getInt("mgr"));
e.setHiredate(rs.getDate("hiredate"));
e.setSal(rs.getDouble("sal"));
e.setComm(rs.getDouble("comm"));
e.setDeptno(rs.getInt("deptno"));
list.add(e);
}
}
} catch (SQLException e) { e.printStackTrace(); }
return list;
}
}
public class DBConnection {
private static String url, user, pwd, driver;
static { /* 從 properties 載入 */ }
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, user, pwd);
}
public static void close(ResultSet rs, Statement stmt, Connection conn) {
try { if (rs != null) rs.close(); } catch (SQLException e) { e.printStackTrace(); }
try { if (stmt != null) stmt.close(); } catch (SQLException e) { e.printStackTrace(); }
try { if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); }
}
// 通用執行更新/查詢 (簡化 DAO 代碼)
public static int executeUpdate(String sql, Object[] params) { ... }
public static ResultSet executeQuery(String sql, Object[] params) { ... }
}
public class DBConfigUtil {
private static Properties props = new Properties();
static {
try (InputStream in = DBConfigUtil.class.getClassLoader().getResourceAsStream("db.properties")) {
props.load(in);
} catch (IOException e) { e.printStackTrace(); }
}
public static String getProperty(String key) { return props.getProperty(key); }
}
setNull(idx, Types.XXX) 處理可為 NULL 的欄位 (如 mgr)。java.util.Date → java.sql.Date 使用 new java.sql.Date(utilDate.getTime())。CallableStatement + registerOutParameter(OracleTypes.CURSOR) 獲取 REF CURSOR。DBConnection.executeUpdate/Query 減少 DAO 樣板代碼。