001package edu.pdx.cs.joy.jdbc; 002 003import java.sql.*; 004import java.util.ArrayList; 005import java.util.List; 006 007/** 008 * Data Access Object implementation for managing Department entities in the database. 009 * Demonstrates JDBC operations with auto-generated keys: CREATE, READ, UPDATE, DELETE. 010 */ 011public class DepartmentDAOImpl implements DepartmentDAO { 012 013 private final Connection connection; 014 015 /** 016 * Creates a new DepartmentDAOImpl with the specified database connection. 017 * 018 * @param connection the database connection to use 019 */ 020 public DepartmentDAOImpl(Connection connection) { 021 this.connection = connection; 022 } 023 024 /** 025 * Drops the departments table from the database if it exists. 026 * 027 * @param connection the database connection to use 028 * @throws SQLException if a database error occurs 029 */ 030 public static void dropTable(Connection connection) throws SQLException { 031 try (Statement statement = connection.createStatement()) { 032 statement.execute("DROP TABLE IF EXISTS departments"); 033 } 034 } 035 036 /** 037 * Creates the departments table in the database if it does not already exist. 038 * 039 * @param connection the database connection to use 040 * @throws SQLException if a database error occurs 041 */ 042 public static void createTable(Connection connection) throws SQLException { 043 try (Statement statement = connection.createStatement()) { 044 statement.execute( 045 "CREATE TABLE IF NOT EXISTS departments (" + 046 " id IDENTITY PRIMARY KEY," + 047 " name VARCHAR(255) NOT NULL" + 048 ")" 049 ); 050 } 051 } 052 053 /** 054 * Saves a department to the database. 055 * The department's ID will be automatically generated by the database. 056 * 057 * @param department the department to save 058 * @throws SQLException if a database error occurs 059 */ 060 @Override 061 public void save(Department department) throws SQLException { 062 String sql = "INSERT INTO departments (name) VALUES (?)"; 063 064 try (PreparedStatement statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { 065 statement.setString(1, department.getName()); 066 statement.executeUpdate(); 067 068 // Retrieve the auto-generated ID and set it on the department object 069 try (ResultSet generatedKeys = statement.getGeneratedKeys()) { 070 if (generatedKeys.next()) { 071 int generatedId = generatedKeys.getInt(1); 072 department.setId(generatedId); 073 } else { 074 throw new SQLException("Creating department failed, no ID obtained."); 075 } 076 } 077 } 078 } 079 080 /** 081 * Finds a department by its ID. 082 * 083 * @param id the ID to search for 084 * @return the department with the given ID, or null if not found 085 * @throws SQLException if a database error occurs 086 */ 087 @Override 088 public Department findById(int id) throws SQLException { 089 String sql = "SELECT id, name FROM departments WHERE id = ?"; 090 091 try (PreparedStatement statement = connection.prepareStatement(sql)) { 092 statement.setInt(1, id); 093 094 try (ResultSet resultSet = statement.executeQuery()) { 095 if (resultSet.next()) { 096 return extractDepartmentFromResultSet(resultSet); 097 } 098 } 099 } 100 101 return null; 102 } 103 104 /** 105 * Finds a department by its name. 106 * 107 * @param name the name to search for 108 * @return the department with the given name, or null if not found 109 * @throws SQLException if a database error occurs 110 */ 111 @Override 112 public Department findByName(String name) throws SQLException { 113 String sql = "SELECT id, name FROM departments WHERE name = ?"; 114 115 try (PreparedStatement statement = connection.prepareStatement(sql)) { 116 statement.setString(1, name); 117 118 try (ResultSet resultSet = statement.executeQuery()) { 119 if (resultSet.next()) { 120 return extractDepartmentFromResultSet(resultSet); 121 } 122 } 123 } 124 125 return null; 126 } 127 128 /** 129 * Finds all departments in the database. 130 * 131 * @return a list of all departments 132 * @throws SQLException if a database error occurs 133 */ 134 @Override 135 public List<Department> findAll() throws SQLException { 136 List<Department> departments = new ArrayList<>(); 137 String sql = "SELECT id, name FROM departments ORDER BY id"; 138 139 try (Statement statement = connection.createStatement(); 140 ResultSet resultSet = statement.executeQuery(sql)) { 141 while (resultSet.next()) { 142 departments.add(extractDepartmentFromResultSet(resultSet)); 143 } 144 } 145 146 return departments; 147 } 148 149 /** 150 * Extracts a Department object from the current row of a ResultSet. 151 * 152 * @param resultSet the result set positioned at a department row 153 * @return a Department object with data from the result set 154 * @throws SQLException if a database error occurs 155 */ 156 private Department extractDepartmentFromResultSet(ResultSet resultSet) throws SQLException { 157 int id = resultSet.getInt("id"); 158 String name = resultSet.getString("name"); 159 return new Department(id, name); 160 } 161 162 /** 163 * Updates an existing department in the database. 164 * 165 * @param department the department to update 166 * @throws SQLException if a database error occurs 167 */ 168 @Override 169 public void update(Department department) throws SQLException { 170 String sql = "UPDATE departments SET name = ? WHERE id = ?"; 171 172 try (PreparedStatement statement = connection.prepareStatement(sql)) { 173 statement.setString(1, department.getName()); 174 statement.setInt(2, department.getId()); 175 int rowsAffected = statement.executeUpdate(); 176 177 if (rowsAffected == 0) { 178 throw new SQLException("Update failed, no department found with ID: " + department.getId()); 179 } 180 } 181 } 182 183 /** 184 * Deletes a department from the database by ID. 185 * 186 * @param id the ID of the department to delete 187 * @throws SQLException if a database error occurs 188 */ 189 @Override 190 public void delete(int id) throws SQLException { 191 String sql = "DELETE FROM departments WHERE id = ?"; 192 193 try (PreparedStatement statement = connection.prepareStatement(sql)) { 194 statement.setInt(1, id); 195 int rowsAffected = statement.executeUpdate(); 196 197 if (rowsAffected == 0) { 198 throw new SQLException("Delete failed, no department found with ID: " + id); 199 } 200 } 201 } 202} 203 204