diff --git a/src/main/java/core/jdbc/JdbcTemplate.java b/src/main/java/core/jdbc/JdbcTemplate.java new file mode 100644 index 000000000..1f4ad5c11 --- /dev/null +++ b/src/main/java/core/jdbc/JdbcTemplate.java @@ -0,0 +1,71 @@ +package core.jdbc; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class JdbcTemplate { + private R execute(String query, + ParameterSetter parameterSetter, + StatementExecutor executor) { + try (Connection conn = ConnectionManager.getConnection(); + PreparedStatement stmt = conn.prepareStatement(query)){ + parameterSetter.setParams(stmt); + return executor.execute(stmt); + } catch(SQLException e) { + throw new DataAccessException(e); + } + } + + public void insert(String query, Object... params) { + execute(query, stmt -> parameterSetter(stmt, params), PreparedStatement::execute); + } + + public Optional queryForObject(String query, RowMapper mapper, Object... params) { + List rows = findAll(query, stmt -> parameterSetter(stmt, params), mapper); + if (rows.size() > 0) { + return Optional.of(rows.get(0)); + } + return Optional.empty(); + } + + public List findAll(String query, RowMapper mapper, Object... params) { + return execute(query, stmt -> parameterSetter(stmt, params), stmt -> fetchAllRows(stmt, mapper)); + } + + public List findAll(String query, ParameterSetter parameterSetter, RowMapper mapper) { + return execute(query, parameterSetter, stmt -> fetchAllRows(stmt, mapper)); + } + + private void parameterSetter(PreparedStatement stmt, Object[] params) throws SQLException { + int i = 1; + for(Object param : params) { + stmt.setObject(i++, param); + } + } + + private List fetchAllRows(PreparedStatement stmt, RowMapper mapper) throws SQLException { + List rows = new ArrayList<>(); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + rows.add(mapper.map(rs)); + } + } + return rows; + } +} + +class DataAccessException extends RuntimeException { + public DataAccessException(Throwable cause) { + super(cause); + } +} + +@FunctionalInterface +interface StatementExecutor { + R execute(PreparedStatement stmt) throws SQLException; +} \ No newline at end of file diff --git a/src/main/java/core/jdbc/ParameterSetter.java b/src/main/java/core/jdbc/ParameterSetter.java new file mode 100644 index 000000000..04fa883fa --- /dev/null +++ b/src/main/java/core/jdbc/ParameterSetter.java @@ -0,0 +1,9 @@ +package core.jdbc; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@FunctionalInterface +public interface ParameterSetter { + void setParams(PreparedStatement rs) throws SQLException; +} diff --git a/src/main/java/core/jdbc/RowMapper.java b/src/main/java/core/jdbc/RowMapper.java new file mode 100644 index 000000000..2f2252d7b --- /dev/null +++ b/src/main/java/core/jdbc/RowMapper.java @@ -0,0 +1,9 @@ +package core.jdbc; + +import java.sql.ResultSet; +import java.sql.SQLException; + +@FunctionalInterface +public interface RowMapper { + T map(ResultSet rs) throws SQLException; +} diff --git a/src/main/java/next/dao/UserDao.java b/src/main/java/next/dao/UserDao.java index db270861f..bb05efcba 100644 --- a/src/main/java/next/dao/UserDao.java +++ b/src/main/java/next/dao/UserDao.java @@ -1,78 +1,40 @@ package next.dao; -import java.sql.Connection; -import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; import java.util.List; -import core.jdbc.ConnectionManager; +import core.jdbc.JdbcTemplate; import next.model.User; public class UserDao { - public void insert(User user) throws SQLException { - Connection con = null; - PreparedStatement pstmt = null; - try { - con = ConnectionManager.getConnection(); - String sql = "INSERT INTO USERS VALUES (?, ?, ?, ?)"; - pstmt = con.prepareStatement(sql); - pstmt.setString(1, user.getUserId()); - pstmt.setString(2, user.getPassword()); - pstmt.setString(3, user.getName()); - pstmt.setString(4, user.getEmail()); + private final JdbcTemplate template; - pstmt.executeUpdate(); - } finally { - if (pstmt != null) { - pstmt.close(); - } - - if (con != null) { - con.close(); - } - } + public UserDao() { + template = new JdbcTemplate(); } - - public void update(User user) throws SQLException { - // TODO 구현 필요함. + public void insert(User user) { + String sql = "INSERT INTO USERS VALUES (?, ?, ?, ?)"; + template.insert(sql, user.getUserId(), user.getPassword(), user.getName(), user.getEmail()); } - public List findAll() throws SQLException { - // TODO 구현 필요함. - return new ArrayList(); + public void update(User user) { + String sql = "UPDATE \"USERS\" SET password =?, name = ?, email = ? WHERE userId = ?"; + template.insert(sql, user.getPassword(), user.getName(), user.getEmail(), user.getUserId()); } - public User findByUserId(String userId) throws SQLException { - Connection con = null; - PreparedStatement pstmt = null; - ResultSet rs = null; - try { - con = ConnectionManager.getConnection(); - String sql = "SELECT userId, password, name, email FROM USERS WHERE userid=?"; - pstmt = con.prepareStatement(sql); - pstmt.setString(1, userId); - - rs = pstmt.executeQuery(); + public List findAll() { + String sql = "SELECT * FROM USERS"; + return template.findAll(sql, UserDao::mapRow); + } - User user = null; - if (rs.next()) { - user = new User(rs.getString("userId"), rs.getString("password"), rs.getString("name"), - rs.getString("email")); - } + public User findByUserId(String userId) { + String sql = "SELECT userId, password, name, email FROM USERS WHERE userid=?"; + return template.queryForObject(sql, UserDao::mapRow, userId).get(); + } - return user; - } finally { - if (rs != null) { - rs.close(); - } - if (pstmt != null) { - pstmt.close(); - } - if (con != null) { - con.close(); - } - } + private static User mapRow(ResultSet rs) throws SQLException { + return new User(rs.getString("userId"), rs.getString("password"), rs.getString("name"), + rs.getString("email")); } }