From 4d32d5f30d3f3b5561b6743dd93a7cf1acd93de9 Mon Sep 17 00:00:00 2001 From: HubCreator Date: Tue, 26 Sep 2023 17:44:49 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20JdbcTemplate=20=EB=BC=88=EB=8C=80?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20findById=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/techcourse/dao/UserDaoTest.java | 16 +++++++++++-- .../jdbc/core/JdbcTemplate.java | 22 +++++++++++++++++- .../springframework/jdbc/core/RowMapper.java | 23 +++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 jdbc/src/main/java/org/springframework/jdbc/core/RowMapper.java diff --git a/app/src/test/java/com/techcourse/dao/UserDaoTest.java b/app/src/test/java/com/techcourse/dao/UserDaoTest.java index 773d7faf82..a69fff3341 100644 --- a/app/src/test/java/com/techcourse/dao/UserDaoTest.java +++ b/app/src/test/java/com/techcourse/dao/UserDaoTest.java @@ -5,16 +5,20 @@ import com.techcourse.support.jdbc.init.DatabasePopulatorUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; import static org.assertj.core.api.Assertions.assertThat; class UserDaoTest { private UserDao userDao; + private JdbcTemplate template; @BeforeEach void setup() { DatabasePopulatorUtils.execute(DataSourceConfig.getInstance()); + template = new JdbcTemplate(DataSourceConfig.getInstance()); userDao = new UserDao(DataSourceConfig.getInstance()); final var user = new User("gugu", "password", "hkkang@woowahan.com"); @@ -30,8 +34,8 @@ void findAll() { @Test void findById() { - final var user = userDao.findById(1L); - + final String sql = "select id, account, password, email from users where id = ?"; + final User user = template.queryForObject(sql, userRowMapper(), 1L); assertThat(user.getAccount()).isEqualTo("gugu"); } @@ -66,4 +70,12 @@ void update() { assertThat(actual.getPassword()).isEqualTo(newPassword); } + + private RowMapper userRowMapper() { + return (rs, rowNum) -> new User( + rs.getString("account"), + rs.getString("password"), + rs.getString("email") + ); + } } diff --git a/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java b/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java index 52a0d30a17..07f5f77fc1 100644 --- a/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java +++ b/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java @@ -4,9 +4,12 @@ import org.slf4j.LoggerFactory; import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; public class JdbcTemplate { - private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class); private final DataSource dataSource; @@ -14,4 +17,21 @@ public class JdbcTemplate { public JdbcTemplate(final DataSource dataSource) { this.dataSource = dataSource; } + + public T queryForObject(final String sql, final RowMapper rowMapper, Object... args) { + try (final Connection conn = dataSource.getConnection(); + final PreparedStatement pstmt = conn.prepareStatement(sql)) { + for (int i = 0; i < args.length; i++) { + pstmt.setObject(i + 1, args[i]); + } + try (final ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + return rowMapper.mapRow(rs, 1); + } + return null; + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + } } diff --git a/jdbc/src/main/java/org/springframework/jdbc/core/RowMapper.java b/jdbc/src/main/java/org/springframework/jdbc/core/RowMapper.java new file mode 100644 index 0000000000..bae511861b --- /dev/null +++ b/jdbc/src/main/java/org/springframework/jdbc/core/RowMapper.java @@ -0,0 +1,23 @@ +package org.springframework.jdbc.core; + +import javax.annotation.Nullable; +import java.sql.ResultSet; +import java.sql.SQLException; + +@FunctionalInterface +public interface RowMapper { + + /** + * Implementations must implement this method to map each row of data in the + * {@code ResultSet}. This method should not call {@code next()} on the + * {@code ResultSet}; it is only supposed to map values of the current row. + * @param rs the {@code ResultSet} to map (pre-initialized for the current row) + * @param rowNum the number of the current row + * @return the result object for the current row (may be {@code null}) + * @throws SQLException if an SQLException is encountered while getting + * column values (that is, there's no need to catch SQLException) + */ + @Nullable + T mapRow(ResultSet rs, int rowNum) throws SQLException; + +} From 7bf90f8b4be472b7d28fb533d8078e6472502e57 Mon Sep 17 00:00:00 2001 From: HubCreator Date: Wed, 27 Sep 2023 23:14:25 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20findAll()=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/techcourse/dao/UserDaoTest.java | 6 +++-- .../jdbc/core/JdbcTemplate.java | 25 +++++++++++++++++-- .../springframework/jdbc/core/RowMapper.java | 12 +-------- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/app/src/test/java/com/techcourse/dao/UserDaoTest.java b/app/src/test/java/com/techcourse/dao/UserDaoTest.java index a69fff3341..c1887c4f1f 100644 --- a/app/src/test/java/com/techcourse/dao/UserDaoTest.java +++ b/app/src/test/java/com/techcourse/dao/UserDaoTest.java @@ -8,6 +8,8 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; +import java.util.List; + import static org.assertj.core.api.Assertions.assertThat; class UserDaoTest { @@ -27,8 +29,8 @@ void setup() { @Test void findAll() { - final var users = userDao.findAll(); - + final String sql = "select * from users"; + final List users = template.query(sql, userRowMapper()); assertThat(users).isNotEmpty(); } diff --git a/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java b/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java index 07f5f77fc1..34981cbf75 100644 --- a/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java +++ b/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java @@ -2,12 +2,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.dao.DataAccessException; import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; public class JdbcTemplate { private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class); @@ -26,11 +29,29 @@ public T queryForObject(final String sql, final RowMapper rowMapper, Obje } try (final ResultSet rs = pstmt.executeQuery()) { if (rs.next()) { - return rowMapper.mapRow(rs, 1); + return rowMapper.mapRow(rs); } return null; } - } catch (SQLException e) { + } catch (final SQLException e) { + log.error(e.getMessage(), e); + throw new RuntimeException(e); + } + } + + public List query(String sql, RowMapper rowMapper) throws DataAccessException { + try (final Connection conn = dataSource.getConnection(); + final PreparedStatement pstmt = conn.prepareStatement(sql)) { + final List result = new ArrayList<>(); + try (final ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + result.add(rowMapper.mapRow(rs)); + } + return result; + } + + } catch (final SQLException e) { + log.error(e.getMessage(), e); throw new RuntimeException(e); } } diff --git a/jdbc/src/main/java/org/springframework/jdbc/core/RowMapper.java b/jdbc/src/main/java/org/springframework/jdbc/core/RowMapper.java index bae511861b..7831de14a6 100644 --- a/jdbc/src/main/java/org/springframework/jdbc/core/RowMapper.java +++ b/jdbc/src/main/java/org/springframework/jdbc/core/RowMapper.java @@ -7,17 +7,7 @@ @FunctionalInterface public interface RowMapper { - /** - * Implementations must implement this method to map each row of data in the - * {@code ResultSet}. This method should not call {@code next()} on the - * {@code ResultSet}; it is only supposed to map values of the current row. - * @param rs the {@code ResultSet} to map (pre-initialized for the current row) - * @param rowNum the number of the current row - * @return the result object for the current row (may be {@code null}) - * @throws SQLException if an SQLException is encountered while getting - * column values (that is, there's no need to catch SQLException) - */ @Nullable - T mapRow(ResultSet rs, int rowNum) throws SQLException; + T mapRow(ResultSet rs) throws SQLException; } From b7063c3283d8957c237483adeadf9842fb297626 Mon Sep 17 00:00:00 2001 From: HubCreator Date: Wed, 27 Sep 2023 23:31:02 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20update,=20insert=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/java/com/techcourse/dao/UserDaoTest.java | 10 ++++++---- .../org/springframework/jdbc/core/JdbcTemplate.java | 13 +++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/src/test/java/com/techcourse/dao/UserDaoTest.java b/app/src/test/java/com/techcourse/dao/UserDaoTest.java index c1887c4f1f..0e52fcdf0a 100644 --- a/app/src/test/java/com/techcourse/dao/UserDaoTest.java +++ b/app/src/test/java/com/techcourse/dao/UserDaoTest.java @@ -53,7 +53,9 @@ void findByAccount() { void insert() { final var account = "insert-gugu"; final var user = new User(account, "password", "hkkang@woowahan.com"); - userDao.insert(user); + final String sql1 = "insert into users(account, password, email) values(?, ?, ?)"; + + final int updatedRow = template.update(sql1, user.getAccount(), user.getPassword(), user.getEmail()); final var actual = userDao.findById(2L); @@ -66,15 +68,15 @@ void update() { final var user = userDao.findById(1L); user.changePassword(newPassword); - userDao.update(user); - + final String sql2 = "update users set password = ? where id = ?"; + template.update(sql2, user.getPassword(), user.getId()); final var actual = userDao.findById(1L); assertThat(actual.getPassword()).isEqualTo(newPassword); } private RowMapper userRowMapper() { - return (rs, rowNum) -> new User( + return rs -> new User( rs.getString("account"), rs.getString("password"), rs.getString("email") diff --git a/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java b/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java index 34981cbf75..aa6e75c595 100644 --- a/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java +++ b/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java @@ -55,4 +55,17 @@ public List query(String sql, RowMapper rowMapper) throws DataAccessEx throw new RuntimeException(e); } } + + public int update(final String sql, final Object... args) { + try (final Connection conn = dataSource.getConnection(); + final PreparedStatement pstmt = conn.prepareStatement(sql)) { + for (int i = 0; i < args.length; i++) { + pstmt.setObject(i + 1, args[i]); + } + return pstmt.executeUpdate(); + } catch (final SQLException e) { + log.error(e.getMessage(), e); + throw new RuntimeException(e); + } + } } From 875b5b427a68769fbee3fa0992181e4515aeb685 Mon Sep 17 00:00:00 2001 From: HubCreator Date: Wed, 27 Sep 2023 23:34:34 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20findByAccount=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/java/com/techcourse/dao/UserDaoTest.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/src/test/java/com/techcourse/dao/UserDaoTest.java b/app/src/test/java/com/techcourse/dao/UserDaoTest.java index 0e52fcdf0a..aed927ed25 100644 --- a/app/src/test/java/com/techcourse/dao/UserDaoTest.java +++ b/app/src/test/java/com/techcourse/dao/UserDaoTest.java @@ -29,22 +29,25 @@ void setup() { @Test void findAll() { - final String sql = "select * from users"; + final String sql = "SELECT id, account, password, email FROM users"; final List users = template.query(sql, userRowMapper()); + assertThat(users).isNotEmpty(); } @Test void findById() { - final String sql = "select id, account, password, email from users where id = ?"; + final String sql = "SELECT id, account, password, email FROM users WHERE id = ?"; final User user = template.queryForObject(sql, userRowMapper(), 1L); + assertThat(user.getAccount()).isEqualTo("gugu"); } @Test void findByAccount() { final var account = "gugu"; - final var user = userDao.findByAccount(account); + final String sql = "SELECT id, account, password, email FROM users WHERE account = ?"; + final var user = template.queryForObject(sql, userRowMapper(), account); assertThat(user.getAccount()).isEqualTo(account); } @@ -53,8 +56,7 @@ void findByAccount() { void insert() { final var account = "insert-gugu"; final var user = new User(account, "password", "hkkang@woowahan.com"); - final String sql1 = "insert into users(account, password, email) values(?, ?, ?)"; - + final String sql1 = "INSERT INTO users(account, password, email) VALUES(?, ?, ?)"; final int updatedRow = template.update(sql1, user.getAccount(), user.getPassword(), user.getEmail()); final var actual = userDao.findById(2L); @@ -68,7 +70,7 @@ void update() { final var user = userDao.findById(1L); user.changePassword(newPassword); - final String sql2 = "update users set password = ? where id = ?"; + final String sql2 = "UPDATE users SET password = ? WHERE id = ?"; template.update(sql2, user.getPassword(), user.getId()); final var actual = userDao.findById(1L); From 9faa5c64df73f1aa7cd338e3324693987145896c Mon Sep 17 00:00:00 2001 From: HubCreator Date: Wed, 27 Sep 2023 23:42:16 +0900 Subject: [PATCH 5/8] =?UTF-8?q?refactor:=20queryForObject=EC=9D=98=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=20=ED=83=80=EC=9E=85=EC=9D=84=20Optional?= =?UTF-8?q?=EB=A1=9C=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/java/com/techcourse/dao/UserDaoTest.java | 4 ++-- .../springframework/jdbc/core/JdbcTemplate.java | 14 ++++---------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/app/src/test/java/com/techcourse/dao/UserDaoTest.java b/app/src/test/java/com/techcourse/dao/UserDaoTest.java index aed927ed25..61bab349bd 100644 --- a/app/src/test/java/com/techcourse/dao/UserDaoTest.java +++ b/app/src/test/java/com/techcourse/dao/UserDaoTest.java @@ -38,7 +38,7 @@ void findAll() { @Test void findById() { final String sql = "SELECT id, account, password, email FROM users WHERE id = ?"; - final User user = template.queryForObject(sql, userRowMapper(), 1L); + final User user = template.queryForObject(sql, userRowMapper(), 1L).orElseThrow(); assertThat(user.getAccount()).isEqualTo("gugu"); } @@ -47,7 +47,7 @@ void findById() { void findByAccount() { final var account = "gugu"; final String sql = "SELECT id, account, password, email FROM users WHERE account = ?"; - final var user = template.queryForObject(sql, userRowMapper(), account); + final User user = template.queryForObject(sql, userRowMapper(), account).orElseThrow(); assertThat(user.getAccount()).isEqualTo(account); } diff --git a/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java b/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java index aa6e75c595..4e259aa363 100644 --- a/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java +++ b/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java @@ -1,7 +1,5 @@ package org.springframework.jdbc.core; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.dao.DataAccessException; import javax.sql.DataSource; @@ -11,17 +9,16 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import java.util.Optional; public class JdbcTemplate { - private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class); - private final DataSource dataSource; public JdbcTemplate(final DataSource dataSource) { this.dataSource = dataSource; } - public T queryForObject(final String sql, final RowMapper rowMapper, Object... args) { + public Optional queryForObject(final String sql, final RowMapper rowMapper, Object... args) { try (final Connection conn = dataSource.getConnection(); final PreparedStatement pstmt = conn.prepareStatement(sql)) { for (int i = 0; i < args.length; i++) { @@ -29,12 +26,11 @@ public T queryForObject(final String sql, final RowMapper rowMapper, Obje } try (final ResultSet rs = pstmt.executeQuery()) { if (rs.next()) { - return rowMapper.mapRow(rs); + return Optional.ofNullable(rowMapper.mapRow(rs)); } - return null; + return Optional.empty(); } } catch (final SQLException e) { - log.error(e.getMessage(), e); throw new RuntimeException(e); } } @@ -51,7 +47,6 @@ public List query(String sql, RowMapper rowMapper) throws DataAccessEx } } catch (final SQLException e) { - log.error(e.getMessage(), e); throw new RuntimeException(e); } } @@ -64,7 +59,6 @@ public int update(final String sql, final Object... args) { } return pstmt.executeUpdate(); } catch (final SQLException e) { - log.error(e.getMessage(), e); throw new RuntimeException(e); } } From c89e5723380a4733d001d8d2b2faef659100e536 Mon Sep 17 00:00:00 2001 From: HubCreator Date: Wed, 27 Sep 2023 23:55:14 +0900 Subject: [PATCH 6/8] =?UTF-8?q?refactor:=20=EC=98=88=EC=99=B8=20=EB=B3=80?= =?UTF-8?q?=ED=99=98=20=ED=83=80=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/springframework/jdbc/core/JdbcTemplate.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java b/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java index 4e259aa363..527c7c86e8 100644 --- a/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java +++ b/jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java @@ -31,7 +31,7 @@ public Optional queryForObject(final String sql, final RowMapper rowMa return Optional.empty(); } } catch (final SQLException e) { - throw new RuntimeException(e); + throw new DataAccessException(e); } } @@ -47,7 +47,7 @@ public List query(String sql, RowMapper rowMapper) throws DataAccessEx } } catch (final SQLException e) { - throw new RuntimeException(e); + throw new DataAccessException(e); } } @@ -59,7 +59,7 @@ public int update(final String sql, final Object... args) { } return pstmt.executeUpdate(); } catch (final SQLException e) { - throw new RuntimeException(e); + throw new DataAccessException(e); } } } From db5f5fdc4906496caca30d1eada375fd91dd87f1 Mon Sep 17 00:00:00 2001 From: HubCreator Date: Fri, 29 Sep 2023 20:24:58 +0900 Subject: [PATCH 7/8] =?UTF-8?q?refactor:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EB=A1=A4=EB=B0=B1=20=EB=B0=8F=20?= =?UTF-8?q?UserDao=EB=A1=9C=20=EB=A1=9C=EC=A7=81=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/techcourse/dao/UserDao.java | 117 ++++-------------- .../com/techcourse/service/UserService.java | 6 +- .../java/com/techcourse/dao/UserDaoTest.java | 37 ++---- .../techcourse/service/UserServiceTest.java | 8 +- 4 files changed, 43 insertions(+), 125 deletions(-) diff --git a/app/src/main/java/com/techcourse/dao/UserDao.java b/app/src/main/java/com/techcourse/dao/UserDao.java index d14c545f34..96002b4bbf 100644 --- a/app/src/main/java/com/techcourse/dao/UserDao.java +++ b/app/src/main/java/com/techcourse/dao/UserDao.java @@ -1,121 +1,54 @@ package com.techcourse.dao; import com.techcourse.domain.User; -import org.springframework.jdbc.core.JdbcTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; -import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; import java.util.List; +import java.util.Optional; public class UserDao { - private static final Logger log = LoggerFactory.getLogger(UserDao.class); - private final DataSource dataSource; + private final JdbcTemplate template; - public UserDao(final DataSource dataSource) { - this.dataSource = dataSource; - } - - public UserDao(final JdbcTemplate jdbcTemplate) { - this.dataSource = null; + public UserDao(final JdbcTemplate template) { + this.template = template; } public void insert(final User user) { final var sql = "insert into users (account, password, email) values (?, ?, ?)"; - - Connection conn = null; - PreparedStatement pstmt = null; - try { - conn = dataSource.getConnection(); - pstmt = conn.prepareStatement(sql); - - log.debug("query : {}", sql); - - pstmt.setString(1, user.getAccount()); - pstmt.setString(2, user.getPassword()); - pstmt.setString(3, user.getEmail()); - pstmt.executeUpdate(); - } catch (SQLException e) { - log.error(e.getMessage(), e); - throw new RuntimeException(e); - } finally { - try { - if (pstmt != null) { - pstmt.close(); - } - } catch (SQLException ignored) {} - - try { - if (conn != null) { - conn.close(); - } - } catch (SQLException ignored) {} - } + template.update(sql, user.getAccount(), user.getPassword(), user.getEmail()); } public void update(final User user) { - // todo + final var sql = "update users set password = ? where id = ?"; + template.update(sql, user.getPassword(), user.getId()); } public List findAll() { - // todo - return null; + final String sql = "select id, account, password, email from users"; + return template.query(sql, userRowMapper()); } - public User findById(final Long id) { - final var sql = "select id, account, password, email from users where id = ?"; - - Connection conn = null; - PreparedStatement pstmt = null; - ResultSet rs = null; - try { - conn = dataSource.getConnection(); - pstmt = conn.prepareStatement(sql); - pstmt.setLong(1, id); - rs = pstmt.executeQuery(); - - log.debug("query : {}", sql); - - if (rs.next()) { - return new User( - rs.getLong(1), - rs.getString(2), - rs.getString(3), - rs.getString(4)); - } - return null; - } catch (SQLException e) { - log.error(e.getMessage(), e); - throw new RuntimeException(e); - } finally { - try { - if (rs != null) { - rs.close(); - } - } catch (SQLException ignored) {} - - try { - if (pstmt != null) { - pstmt.close(); - } - } catch (SQLException ignored) {} + public Optional findById(final Long id) { + final String sql = "select id, account, password, email from users where id = ?"; + return template.queryForObject(sql, userRowMapper(), id); + } - try { - if (conn != null) { - conn.close(); - } - } catch (SQLException ignored) {} - } + public Optional findByAccount(final String account) { + final String sql = "select id, account, password, email from users where account = ?"; + return template.queryForObject(sql, userRowMapper(), account); } - public User findByAccount(final String account) { - // todo - return null; + private RowMapper userRowMapper() { + return rs -> new User( + rs.getLong("id"), + rs.getString("account"), + rs.getString("password"), + rs.getString("email") + ); } } diff --git a/app/src/main/java/com/techcourse/service/UserService.java b/app/src/main/java/com/techcourse/service/UserService.java index fcf2159dc8..9e9feb06dd 100644 --- a/app/src/main/java/com/techcourse/service/UserService.java +++ b/app/src/main/java/com/techcourse/service/UserService.java @@ -5,6 +5,8 @@ import com.techcourse.domain.User; import com.techcourse.domain.UserHistory; +import java.util.Optional; + public class UserService { private final UserDao userDao; @@ -15,7 +17,7 @@ public UserService(final UserDao userDao, final UserHistoryDao userHistoryDao) { this.userHistoryDao = userHistoryDao; } - public User findById(final long id) { + public Optional findById(final long id) { return userDao.findById(id); } @@ -24,7 +26,7 @@ public void insert(final User user) { } public void changePassword(final long id, final String newPassword, final String createBy) { - final var user = findById(id); + final var user = findById(id).orElseThrow(() -> new IllegalArgumentException("해당 유저가 존재하지 않습니다.")); user.changePassword(newPassword); userDao.update(user); userHistoryDao.log(new UserHistory(user, createBy)); diff --git a/app/src/test/java/com/techcourse/dao/UserDaoTest.java b/app/src/test/java/com/techcourse/dao/UserDaoTest.java index 61bab349bd..a3eb897148 100644 --- a/app/src/test/java/com/techcourse/dao/UserDaoTest.java +++ b/app/src/test/java/com/techcourse/dao/UserDaoTest.java @@ -6,39 +6,32 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; - -import java.util.List; import static org.assertj.core.api.Assertions.assertThat; class UserDaoTest { private UserDao userDao; - private JdbcTemplate template; @BeforeEach void setup() { DatabasePopulatorUtils.execute(DataSourceConfig.getInstance()); - template = new JdbcTemplate(DataSourceConfig.getInstance()); - userDao = new UserDao(DataSourceConfig.getInstance()); + userDao = new UserDao(new JdbcTemplate(DataSourceConfig.getInstance())); final var user = new User("gugu", "password", "hkkang@woowahan.com"); userDao.insert(user); } @Test void findAll() { - final String sql = "SELECT id, account, password, email FROM users"; - final List users = template.query(sql, userRowMapper()); + final var users = userDao.findAll(); assertThat(users).isNotEmpty(); } @Test void findById() { - final String sql = "SELECT id, account, password, email FROM users WHERE id = ?"; - final User user = template.queryForObject(sql, userRowMapper(), 1L).orElseThrow(); + final var user = userDao.findById(1L).orElseThrow(); assertThat(user.getAccount()).isEqualTo("gugu"); } @@ -46,8 +39,7 @@ void findById() { @Test void findByAccount() { final var account = "gugu"; - final String sql = "SELECT id, account, password, email FROM users WHERE account = ?"; - final User user = template.queryForObject(sql, userRowMapper(), account).orElseThrow(); + final var user = userDao.findByAccount(account).orElseThrow(); assertThat(user.getAccount()).isEqualTo(account); } @@ -56,10 +48,9 @@ void findByAccount() { void insert() { final var account = "insert-gugu"; final var user = new User(account, "password", "hkkang@woowahan.com"); - final String sql1 = "INSERT INTO users(account, password, email) VALUES(?, ?, ?)"; - final int updatedRow = template.update(sql1, user.getAccount(), user.getPassword(), user.getEmail()); + userDao.insert(user); - final var actual = userDao.findById(2L); + final var actual = userDao.findById(2L).orElseThrow(); assertThat(actual.getAccount()).isEqualTo(account); } @@ -67,21 +58,13 @@ void insert() { @Test void update() { final var newPassword = "password99"; - final var user = userDao.findById(1L); + final var user = userDao.findById(1L).orElseThrow(); + user.changePassword(newPassword); + userDao.update(user); - final String sql2 = "UPDATE users SET password = ? WHERE id = ?"; - template.update(sql2, user.getPassword(), user.getId()); - final var actual = userDao.findById(1L); + final var actual = userDao.findById(1L).orElseThrow(); assertThat(actual.getPassword()).isEqualTo(newPassword); } - - private RowMapper userRowMapper() { - return rs -> new User( - rs.getString("account"), - rs.getString("password"), - rs.getString("email") - ); - } } diff --git a/app/src/test/java/com/techcourse/service/UserServiceTest.java b/app/src/test/java/com/techcourse/service/UserServiceTest.java index 255a0ebfe7..f13d93dfcb 100644 --- a/app/src/test/java/com/techcourse/service/UserServiceTest.java +++ b/app/src/test/java/com/techcourse/service/UserServiceTest.java @@ -5,11 +5,11 @@ import com.techcourse.dao.UserHistoryDao; import com.techcourse.domain.User; import com.techcourse.support.jdbc.init.DatabasePopulatorUtils; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.core.JdbcTemplate; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -39,7 +39,7 @@ void testChangePassword() { final var createBy = "gugu"; userService.changePassword(1L, newPassword, createBy); - final var actual = userService.findById(1L); + final var actual = userService.findById(1L).orElseThrow(); assertThat(actual.getPassword()).isEqualTo(newPassword); } @@ -56,7 +56,7 @@ void testTransactionRollback() { assertThrows(DataAccessException.class, () -> userService.changePassword(1L, newPassword, createBy)); - final var actual = userService.findById(1L); + final var actual = userService.findById(1L).orElseThrow(); assertThat(actual.getPassword()).isNotEqualTo(newPassword); } From 2cd6c77c9bfad2546c207426434f32c1c69dfa00 Mon Sep 17 00:00:00 2001 From: HubCreator Date: Fri, 29 Sep 2023 20:43:10 +0900 Subject: [PATCH 8/8] =?UTF-8?q?refactor:=20UserDao=EC=9D=98=20RowMapper=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=EA=B0=92=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/techcourse/dao/UserDao.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/techcourse/dao/UserDao.java b/app/src/main/java/com/techcourse/dao/UserDao.java index 96002b4bbf..169fa24269 100644 --- a/app/src/main/java/com/techcourse/dao/UserDao.java +++ b/app/src/main/java/com/techcourse/dao/UserDao.java @@ -10,7 +10,12 @@ import java.util.Optional; public class UserDao { - private static final Logger log = LoggerFactory.getLogger(UserDao.class); + private static final RowMapper USER_ROW_MAPPER = rs -> new User( + rs.getLong("id"), + rs.getString("account"), + rs.getString("password"), + rs.getString("email") + ); private final JdbcTemplate template; @@ -44,11 +49,6 @@ public Optional findByAccount(final String account) { } private RowMapper userRowMapper() { - return rs -> new User( - rs.getLong("id"), - rs.getString("account"), - rs.getString("password"), - rs.getString("email") - ); + return USER_ROW_MAPPER; } }