package dao.impl; import dao.LeaveRequestDAO; import model.ApprovalStatus; import model.LeaveRequest; import model.Student; import util.DatabaseUtil; import java.sql.*; import java.util.ArrayList; import java.util.List; /** * LeaveRequestDAO接口的实现类,提供请假申请的数据库访问操作 * 实现了LeaveRequestDAO接口定义的所有方法,包括基础的CRUD操作和特定的查询方法 * 处理请假申请的创建、更新、查询等操作,支持按学生、状态等条件进行查询 */ public class LeaveRequestDAOImpl implements LeaveRequestDAO { /** * 插入一条请假申请记录 * 将LeaveRequest对象的信息保存到数据库中,并获取生成的主键ID * * @param request 要插入的请假申请对象,包含申请的详细信息 * @return 影响的行数,插入成功返回1,失败返回0 */ @Override public int insert(LeaveRequest request) { if (request == null || request.getStudent() == null) { return 0; } String sql = "INSERT INTO leave_requests (student_id, start_time, end_time, status, " + "duration, location, reason_type, reason_detail, is_leaving_city, " + "request_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; try (Connection conn = DatabaseUtil.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { // 设置预处理语句的参数 stmt.setInt(1, request.getStudent().getId()); stmt.setTimestamp(2, new Timestamp(request.getStartTime().getTime())); stmt.setTimestamp(3, new Timestamp(request.getEndTime().getTime())); stmt.setString(4, request.getStatus().name()); stmt.setDouble(5, request.getDuration()); stmt.setString(6, request.getLocation()); stmt.setString(7, request.getReasonType()); stmt.setString(8, request.getReasonDetail()); stmt.setBoolean(9, request.isLeavingCity()); stmt.setTimestamp(10, new Timestamp(request.getRequestTime().getTime())); int affectedRows = stmt.executeUpdate(); if (affectedRows == 0) { return 0; } // 获取自动生成的主键 try (ResultSet generatedKeys = stmt.getGeneratedKeys()) { if (generatedKeys.next()) { request.setId(generatedKeys.getInt(1)); } } return affectedRows; } catch (SQLException e) { e.printStackTrace(); return 0; } } /** * 根据ID删除请假申请记录 * * @param id 要删除的请假申请记录的ID * @return 影响的行数,删除成功返回1,失败返回0 */ @Override public int deleteById(int id) { String sql = "DELETE FROM leave_requests WHERE id = ?"; try (Connection conn = DatabaseUtil.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setInt(1, id); return stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); return 0; } } /** * 更新请假申请信息 * 根据请假申请对象的ID更新其他字段的值 * * @param request 包含更新信息的请假申请对象 * @return 影响的行数,更新成功返回1,失败返回0 */ @Override public int update(LeaveRequest request) { if (request == null || request.getStudent() == null) { return 0; } String sql = "UPDATE leave_requests SET student_id = ?, start_time = ?, " + "end_time = ?, status = ?, duration = ?, location = ?, " + "reason_type = ?, reason_detail = ?, is_leaving_city = ?, " + "request_time = ? WHERE id = ?"; try (Connection conn = DatabaseUtil.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { // 设置预处理语句的参数 stmt.setInt(1, request.getStudent().getId()); stmt.setTimestamp(2, new Timestamp(request.getStartTime().getTime())); stmt.setTimestamp(3, new Timestamp(request.getEndTime().getTime())); stmt.setString(4, request.getStatus().name()); stmt.setDouble(5, request.getDuration()); stmt.setString(6, request.getLocation()); stmt.setString(7, request.getReasonType()); stmt.setString(8, request.getReasonDetail()); stmt.setBoolean(9, request.isLeavingCity()); stmt.setTimestamp(10, new Timestamp(request.getRequestTime().getTime())); stmt.setInt(11, request.getId()); return stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); return 0; } } /** * 根据ID查询请假申请信息 * 同时会关联查询学生信息 * * @param id 要查询的请假申请ID * @return 如果找到则返回请假申请对象,否则返回null */ @Override public LeaveRequest findById(int id) { String sql = "SELECT lr.*, s.id as student_id, s.student_id as student_number, " + "s.name, s.class_name, s.contact, s.college, s.major " + "FROM leave_requests lr " + "JOIN students s ON lr.student_id = s.id " + "WHERE lr.id = ?"; try (Connection conn = DatabaseUtil.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setInt(1, id); ResultSet rs = stmt.executeQuery(); if (rs.next()) { return mapResultSetToLeaveRequest(rs); } } catch (SQLException e) { e.printStackTrace(); } return null; } /** * 查询所有请假申请记录 * 同时会关联查询每条记录对应的学生信息 * * @return 包含所有请假申请对象的列表,如果没有记录则返回空列表 */ @Override public List findAll() { List requests = new ArrayList<>(); String sql = "SELECT lr.*, s.id as student_id, s.student_id as student_number, " + "s.name, s.class_name, s.contact, s.college, s.major " + "FROM leave_requests lr " + "JOIN students s ON lr.student_id = s.id"; try (Connection conn = DatabaseUtil.getConnection(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)) { while (rs.next()) { requests.add(mapResultSetToLeaveRequest(rs)); } } catch (SQLException e) { e.printStackTrace(); } return requests; } /** * 查询指定学生的所有请假申请记录 * 按请求时间降序排序 * * @param studentId 学生的ID * @return 该学生的所有请假申请列表,如果没有记录则返回空列表 */ @Override public List findByStudentId(int studentId) { List requests = new ArrayList<>(); String sql = "SELECT lr.*, s.id as student_id, s.student_id as student_number, " + "s.name, s.class_name, s.contact, s.college, s.major " + "FROM leave_requests lr " + "JOIN students s ON lr.student_id = s.id " + "WHERE lr.student_id = ? ORDER BY lr.request_time DESC"; try (Connection conn = DatabaseUtil.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setInt(1, studentId); ResultSet rs = stmt.executeQuery(); while (rs.next()) { requests.add(mapResultSetToLeaveRequest(rs)); } } catch (SQLException e) { e.printStackTrace(); } return requests; } /** * 查询指定状态的所有请假申请记录 * * @param status 请假申请的状态 * @return 符合状态条件的请假申请列表,如果没有记录则返回空列表 */ @Override public List findByStatus(ApprovalStatus status) { List requests = new ArrayList<>(); String sql = "SELECT lr.*, s.id as student_id, s.student_id as student_number, " + "s.name, s.class_name, s.contact, s.college, s.major " + "FROM leave_requests lr " + "JOIN students s ON lr.student_id = s.id " + "WHERE lr.status = ? ORDER BY lr.request_time DESC"; try (Connection conn = DatabaseUtil.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, status.name()); ResultSet rs = stmt.executeQuery(); while (rs.next()) { requests.add(mapResultSetToLeaveRequest(rs)); } } catch (SQLException e) { e.printStackTrace(); } return requests; } /** * 更新请假申请状态 * * @param id 请假申请ID * @param status 新的状态 * @param approverComment 审批备注 * @return 影响的行数,更新成功返回1,失败返回0 */ @Override public int updateStatus(int id, ApprovalStatus status, String approverComment) { String sql = "UPDATE leave_requests SET status = ?, approval_comment = ? WHERE id = ?"; try (Connection conn = DatabaseUtil.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, status.name()); stmt.setString(2, approverComment); stmt.setInt(3, id); return stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); return 0; } } /** * 将ResultSet映射为LeaveRequest对象 * 从结果集中提取数据并创建LeaveRequest实例,同时创建关联的Student对象 * * @param rs 包含请假申请和学生数据的ResultSet对象 * @return 映射后的LeaveRequest对象 * @throws SQLException 如果访问ResultSet时发生错误 */ private LeaveRequest mapResultSetToLeaveRequest(ResultSet rs) throws SQLException { // 创建学生对象 Student student = new Student(); student.setId(rs.getInt("student_id")); student.setStudentId(rs.getString("student_number")); student.setName(rs.getString("name")); student.setClassName(rs.getString("class_name")); student.setContact(rs.getString("contact")); student.setCollege(rs.getString("college")); student.setMajor(rs.getString("major")); // 创建请假申请对象 LeaveRequest request = new LeaveRequest(); request.setId(rs.getInt("id")); request.setStudent(student); request.setStartTime(rs.getTimestamp("start_time")); request.setEndTime(rs.getTimestamp("end_time")); request.setStatus(ApprovalStatus.valueOf(rs.getString("status"))); request.setApproverComment(rs.getString("approval_comment")); request.setDuration(rs.getDouble("duration")); request.setLocation(rs.getString("location")); request.setReasonType(rs.getString("reason_type")); request.setReasonDetail(rs.getString("reason_detail")); request.setLeavingCity(rs.getBoolean("is_leaving_city")); request.setRequestTime(rs.getTimestamp("request_time")); Timestamp approvalTime = rs.getTimestamp("approval_time"); if (approvalTime != null) { request.setApprovalTime(approvalTime); } return request; } }