diff --git a/app/src/main/java/com/techcourse/ManualHandlerMapping.java b/app/src/main/java/com/techcourse/ManualHandlerMapping.java index 6d3af40dd4..a4e8f9eb21 100644 --- a/app/src/main/java/com/techcourse/ManualHandlerMapping.java +++ b/app/src/main/java/com/techcourse/ManualHandlerMapping.java @@ -1,6 +1,6 @@ package com.techcourse; -import com.techcourse.controller.*; +import com.techcourse.controller.LogoutController; import jakarta.servlet.http.HttpServletRequest; import nextstep.mvc.HandlerMapping; import nextstep.mvc.controller.asis.Controller; diff --git a/app/src/main/java/com/techcourse/config/DataSourceConfig.java b/app/src/main/java/com/techcourse/config/DataSourceConfig.java index 117e70736a..fdf1aba8b8 100644 --- a/app/src/main/java/com/techcourse/config/DataSourceConfig.java +++ b/app/src/main/java/com/techcourse/config/DataSourceConfig.java @@ -2,13 +2,14 @@ import org.h2.jdbcx.JdbcDataSource; +import javax.sql.DataSource; import java.util.Objects; public class DataSourceConfig { - private static javax.sql.DataSource INSTANCE; + private static DataSource INSTANCE; - public static javax.sql.DataSource getInstance() { + public static DataSource getInstance() { if (Objects.isNull(INSTANCE)) { INSTANCE = createJdbcDataSource(); } @@ -23,5 +24,6 @@ private static JdbcDataSource createJdbcDataSource() { return jdbcDataSource; } - private DataSourceConfig() {} + private DataSourceConfig() { + } } diff --git a/app/src/main/java/com/techcourse/controller/LoginController.java b/app/src/main/java/com/techcourse/controller/LoginController.java index fce596628f..08f2d9f009 100644 --- a/app/src/main/java/com/techcourse/controller/LoginController.java +++ b/app/src/main/java/com/techcourse/controller/LoginController.java @@ -1,12 +1,13 @@ package com.techcourse.controller; +import com.techcourse.dao.UserDao; import com.techcourse.domain.User; -import com.techcourse.repository.InMemoryUserRepository; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import nextstep.mvc.view.JspView; import nextstep.mvc.view.ModelAndView; +import nextstep.mvc.view.util.ViewRedirectHelper; import nextstep.web.annotation.Controller; import nextstep.web.annotation.RequestMapping; import nextstep.web.support.RequestMethod; @@ -23,7 +24,7 @@ public ModelAndView view(HttpServletRequest request, HttpServletResponse respons return UserSession.getUserFrom(request.getSession()) .map(user -> { log.info("logged in {}", user.getAccount()); - return redirect("/index.jsp"); + return ViewRedirectHelper.redirect("/index.jsp"); }) .orElse(new ModelAndView(new JspView("/login.jsp"))); } @@ -31,28 +32,19 @@ public ModelAndView view(HttpServletRequest request, HttpServletResponse respons @RequestMapping(value = "/login", method = RequestMethod.POST) public ModelAndView login(HttpServletRequest request, HttpServletResponse response) { if (UserSession.isLoggedIn(request.getSession())) { - return redirect("/index.jsp"); + return ViewRedirectHelper.redirect("/index.jsp"); } - return InMemoryUserRepository.findByAccount(request.getParameter("account")) - .map(user -> { - log.info("User : {}", user); - return login(request, user); - }) - .orElse(redirect("/401.jsp")); + return login(request, UserDao.findByAccount(request.getParameter("account"))); } private ModelAndView login(HttpServletRequest request, User user) { if (user.checkPassword(request.getParameter("password"))) { final HttpSession session = request.getSession(); session.setAttribute(UserSession.SESSION_KEY, user); - return redirect("/index.jsp"); + return ViewRedirectHelper.redirect("/index.jsp"); } else { - return redirect("/401.jsp"); + return ViewRedirectHelper.redirect("/401.jsp"); } } - - private ModelAndView redirect(String path) { - return new ModelAndView(new JspView(JspView.REDIRECT_PREFIX + path)); - } } diff --git a/app/src/main/java/com/techcourse/controller/RegisterController.java b/app/src/main/java/com/techcourse/controller/RegisterController.java index 1b508a6c69..8dd951744e 100644 --- a/app/src/main/java/com/techcourse/controller/RegisterController.java +++ b/app/src/main/java/com/techcourse/controller/RegisterController.java @@ -1,31 +1,37 @@ package com.techcourse.controller; +import com.techcourse.dao.UserDao; import com.techcourse.domain.User; -import com.techcourse.repository.InMemoryUserRepository; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import nextstep.mvc.view.JspView; import nextstep.mvc.view.ModelAndView; +import nextstep.mvc.view.util.ViewRedirectHelper; import nextstep.web.annotation.Controller; import nextstep.web.annotation.RequestMapping; import nextstep.web.support.RequestMethod; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @Controller public class RegisterController { + private static final Logger log = LoggerFactory.getLogger(RegisterController.class); + @RequestMapping(value = "/register", method = RequestMethod.POST) public ModelAndView register(HttpServletRequest request, HttpServletResponse response) { final User user = new User(2, request.getParameter("account"), request.getParameter("password"), request.getParameter("email")); - InMemoryUserRepository.save(user); - return new ModelAndView(new JspView("redirect:/index.jsp")); + UserDao.insert(user); + return ViewRedirectHelper.redirect("/index.jsp"); } @RequestMapping(value = "/register", method = RequestMethod.GET) public ModelAndView view(HttpServletRequest request, HttpServletResponse response) { return new ModelAndView(new JspView("/register.jsp")); } + } diff --git a/app/src/main/java/com/techcourse/controller/UserController.java b/app/src/main/java/com/techcourse/controller/UserController.java index 3a978b3e6a..24d19880e8 100644 --- a/app/src/main/java/com/techcourse/controller/UserController.java +++ b/app/src/main/java/com/techcourse/controller/UserController.java @@ -1,7 +1,7 @@ package com.techcourse.controller; +import com.techcourse.dao.UserDao; import com.techcourse.domain.User; -import com.techcourse.repository.InMemoryUserRepository; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import nextstep.mvc.view.JsonView; @@ -23,9 +23,8 @@ public ModelAndView show(HttpServletRequest request, HttpServletResponse respons log.debug("user id : {}", account); final ModelAndView modelAndView = new ModelAndView(new JsonView()); - final User user = InMemoryUserRepository.findByAccount(account) - .orElseThrow(); + final User user = UserDao.findByAccount(account); modelAndView.addObject("user", user); return modelAndView; } diff --git a/app/src/main/java/com/techcourse/controller/UserSession.java b/app/src/main/java/com/techcourse/controller/UserSession.java index 5a9e03beb3..241dd1e758 100644 --- a/app/src/main/java/com/techcourse/controller/UserSession.java +++ b/app/src/main/java/com/techcourse/controller/UserSession.java @@ -18,5 +18,6 @@ public static boolean isLoggedIn(HttpSession session) { return getUserFrom(session).isPresent(); } - private UserSession() {} + private UserSession() { + } } diff --git a/app/src/main/java/com/techcourse/dao/UserDao.java b/app/src/main/java/com/techcourse/dao/UserDao.java index 2d8946c390..a0a7a764a5 100644 --- a/app/src/main/java/com/techcourse/dao/UserDao.java +++ b/app/src/main/java/com/techcourse/dao/UserDao.java @@ -1,116 +1,55 @@ package com.techcourse.dao; +import com.techcourse.config.DataSourceConfig; import com.techcourse.domain.User; +import nextstep.jdbc.JdbcTemplate; +import nextstep.jdbc.RowMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; import java.util.List; public class UserDao { private static final Logger log = LoggerFactory.getLogger(UserDao.class); + private static final JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceConfig.getInstance()); - private final DataSource dataSource; - - public UserDao(DataSource dataSource) { - this.dataSource = dataSource; - } - - public void insert(User user) { + public static void insert(User user) { + log.info("UserDao insert Method"); final String 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) {} - } + jdbcTemplate.update(sql, user.getAccount(), user.getPassword(), user.getEmail()); } - public void update(User user) { - // todo + public static void update(User user) { + log.info("UserDao update Method"); + final String sql = "update users set account = ?, password = ?, email = ? where id = ?"; + jdbcTemplate.update(sql, user.getAccount(), user.getPassword(), user.getEmail(), user.getId()); } - public List findAll() { - // todo - return null; + public static List findAll() { + log.info("UserDao findAll Method"); + final String sql = "select id, account, password, email from users"; + return jdbcTemplate.query(sql, userRowMapper()); } - public User findById(Long id) { + public static User findById(Long id) { + log.info("UserDao findById Method"); final String sql = "select id, account, password, email from users where id = ?"; + return jdbcTemplate.queryForObject(sql, userRowMapper(), 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) {} - - try { - if (conn != null) { - conn.close(); - } - } catch (SQLException ignored) {} - } + public static User findByAccount(String account) { + log.info("UserDao findByAccount Method"); + final String sql = "select id, account, password, email from users where account = ?"; + return jdbcTemplate.queryForObject(sql, userRowMapper(), account); } - public User findByAccount(String account) { - // todo - return null; + public static 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/domain/User.java b/app/src/main/java/com/techcourse/domain/User.java index 986721038b..fa34d57f57 100644 --- a/app/src/main/java/com/techcourse/domain/User.java +++ b/app/src/main/java/com/techcourse/domain/User.java @@ -1,5 +1,7 @@ package com.techcourse.domain; +import java.util.Objects; + public class User { private Long id; @@ -44,6 +46,19 @@ public String getPassword() { return password; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + User user = (User) o; + return Objects.equals(id, user.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + @Override public String toString() { return "User{" + diff --git a/app/src/main/java/com/techcourse/repository/InMemoryUserRepository.java b/app/src/main/java/com/techcourse/repository/InMemoryUserRepository.java index b192d2a89d..90ad3aa633 100644 --- a/app/src/main/java/com/techcourse/repository/InMemoryUserRepository.java +++ b/app/src/main/java/com/techcourse/repository/InMemoryUserRepository.java @@ -23,5 +23,6 @@ public static Optional findByAccount(String account) { return Optional.ofNullable(database.get(account)); } - private InMemoryUserRepository() {} + private InMemoryUserRepository() { + } } diff --git a/app/src/main/java/com/techcourse/support/jdbc/init/DatabasePopulatorUtils.java b/app/src/main/java/com/techcourse/support/jdbc/init/DatabasePopulatorUtils.java index 027ac59adf..c6683b74d4 100644 --- a/app/src/main/java/com/techcourse/support/jdbc/init/DatabasePopulatorUtils.java +++ b/app/src/main/java/com/techcourse/support/jdbc/init/DatabasePopulatorUtils.java @@ -17,31 +17,17 @@ public class DatabasePopulatorUtils { private static final Logger log = LoggerFactory.getLogger(DatabasePopulatorUtils.class); public static void execute(DataSource dataSource) { - Connection connection = null; - Statement statement = null; - try { + try (Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement()) { final URL url = DatabasePopulatorUtils.class.getClassLoader().getResource("schema.sql"); final File file = new File(url.getFile()); final String sql = Files.readString(file.toPath()); - connection = dataSource.getConnection(); - statement = connection.createStatement(); statement.execute(sql); } catch (NullPointerException | IOException | SQLException e) { log.error(e.getMessage(), e); - } finally { - try { - if (statement != null) { - statement.close(); - } - } catch (SQLException ignored) {} - - try { - if (connection != null) { - connection.close(); - } - } catch (SQLException ignored) {} } } - private DatabasePopulatorUtils() {} + private DatabasePopulatorUtils() { + } } diff --git a/app/src/test/java/com/techcourse/dao/UserDaoTest.java b/app/src/test/java/com/techcourse/dao/UserDaoTest.java index a0bf15297d..07fbb6b92b 100644 --- a/app/src/test/java/com/techcourse/dao/UserDaoTest.java +++ b/app/src/test/java/com/techcourse/dao/UserDaoTest.java @@ -17,8 +17,7 @@ class UserDaoTest { @BeforeEach void setup() { DatabasePopulatorUtils.execute(DataSourceConfig.getInstance()); - - userDao = new UserDao(DataSourceConfig.getInstance()); + userDao = new UserDao(); final User user = new User("gugu", "password", "hkkang@woowahan.com"); userDao.insert(user); } @@ -26,7 +25,6 @@ void setup() { @Test void findAll() { final List users = userDao.findAll(); - assertThat(users).isNotEmpty(); } diff --git a/jdbc/build.gradle b/jdbc/build.gradle index e7e4546d30..a32c8bcddd 100644 --- a/jdbc/build.gradle +++ b/jdbc/build.gradle @@ -11,6 +11,8 @@ dependencies { implementation 'com.google.guava:guava:29.0-jre' implementation 'org.reflections:reflections:0.9.11' + implementation 'org.apache.tomcat.embed:tomcat-embed-core:10.0.10' + implementation 'com.h2database:h2:1.4.200' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.3' testImplementation 'org.mockito:mockito-core:3.12.3' diff --git a/jdbc/src/main/java/nextstep/jdbc/JdbcPreparedStatementExecution.java b/jdbc/src/main/java/nextstep/jdbc/JdbcPreparedStatementExecution.java new file mode 100644 index 0000000000..0784826a76 --- /dev/null +++ b/jdbc/src/main/java/nextstep/jdbc/JdbcPreparedStatementExecution.java @@ -0,0 +1,10 @@ +package nextstep.jdbc; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@FunctionalInterface +public interface JdbcPreparedStatementExecution { + + T execute(PreparedStatement pstmt) throws SQLException; +} diff --git a/jdbc/src/main/java/nextstep/jdbc/JdbcTemplate.java b/jdbc/src/main/java/nextstep/jdbc/JdbcTemplate.java index b3914f478e..fed3dd8ad3 100644 --- a/jdbc/src/main/java/nextstep/jdbc/JdbcTemplate.java +++ b/jdbc/src/main/java/nextstep/jdbc/JdbcTemplate.java @@ -1,9 +1,77 @@ package nextstep.jdbc; +import nextstep.jdbc.exception.JdbcExecutionException; +import org.checkerframework.checker.nullness.qual.NonNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +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; +import java.util.Objects; + public class JdbcTemplate { private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class); + private final DataSource dataSource; + + public JdbcTemplate(DataSource dataSource) { + this.dataSource = dataSource; + } + + public T queryForObject(String sql, RowMapper rowMapper, @NonNull Object... args) { + log.debug("jdbcTemplate queryForObject method - query : " + sql); + return execute(sql, args, pstmt -> { + try (ResultSet rs = pstmt.executeQuery()) { + T result = null; + while (rs.next()) { + result = rowMapper.mapRow(rs); + } + return result; + } + }); + } + + public List query(String sql, RowMapper rowMapper, @NonNull Object... args) { + log.debug("jdbcTemplate query method - query : " + sql); + return execute(sql, args, pstmt -> { + List results = new ArrayList<>(); + try (ResultSet rs = pstmt.executeQuery()) { + while (rs.next()) { + results.add(rowMapper.mapRow(rs)); + } + return results; + } + }); + } + + public int update(String sql, @NonNull Object... args) { + log.debug("jdbcTemplate update method - query : " + sql); + return execute(sql, args, PreparedStatement::executeUpdate); + } + + private T execute(String sql, Object[] args, JdbcPreparedStatementExecution execution) { + log.debug("jdbcTemplate execute method"); + + try (Connection connection = dataSource.getConnection(); + PreparedStatement pstmt = connection.prepareStatement(sql)) { + setStatementArguments(pstmt, args); + return execution.execute(pstmt); + } catch (SQLException e) { + log.error(e.getMessage()); + throw new JdbcExecutionException(e.getMessage()); + } + } + + private void setStatementArguments(PreparedStatement pstmt, Object[] args) throws SQLException { + if (Objects.nonNull(args)) { + for (int i = 0; i < args.length; i++) { + pstmt.setObject(i + 1, args[i]); + } + } + } } diff --git a/jdbc/src/main/java/nextstep/jdbc/RowMapper.java b/jdbc/src/main/java/nextstep/jdbc/RowMapper.java new file mode 100644 index 0000000000..66ef7abd97 --- /dev/null +++ b/jdbc/src/main/java/nextstep/jdbc/RowMapper.java @@ -0,0 +1,12 @@ +package nextstep.jdbc; + +import javax.annotation.Nullable; +import java.sql.ResultSet; +import java.sql.SQLException; + +@FunctionalInterface +public interface RowMapper { + + @Nullable + T mapRow(ResultSet rs) throws SQLException; +} diff --git a/jdbc/src/main/java/nextstep/jdbc/exception/JdbcException.java b/jdbc/src/main/java/nextstep/jdbc/exception/JdbcException.java new file mode 100644 index 0000000000..74a0f208a0 --- /dev/null +++ b/jdbc/src/main/java/nextstep/jdbc/exception/JdbcException.java @@ -0,0 +1,10 @@ +package nextstep.jdbc.exception; + +public abstract class JdbcException extends RuntimeException { + + private static final String MESSAGE = "JdbcTemplate Occurred!!! Deatiled : "; + + public JdbcException(String message) { + super(MESSAGE + message); + } +} diff --git a/jdbc/src/main/java/nextstep/jdbc/exception/JdbcExecutionException.java b/jdbc/src/main/java/nextstep/jdbc/exception/JdbcExecutionException.java new file mode 100644 index 0000000000..fdbededadd --- /dev/null +++ b/jdbc/src/main/java/nextstep/jdbc/exception/JdbcExecutionException.java @@ -0,0 +1,8 @@ +package nextstep.jdbc.exception; + +public class JdbcExecutionException extends JdbcException { + + public JdbcExecutionException(String message) { + super(message); + } +} diff --git a/jdbc/src/test/java/nextstep/jdbc/DataSourceConfig.java b/jdbc/src/test/java/nextstep/jdbc/DataSourceConfig.java new file mode 100644 index 0000000000..2b41a99314 --- /dev/null +++ b/jdbc/src/test/java/nextstep/jdbc/DataSourceConfig.java @@ -0,0 +1,29 @@ +package nextstep.jdbc; + +import org.h2.jdbcx.JdbcDataSource; + +import javax.sql.DataSource; +import java.util.Objects; + +public class DataSourceConfig { + + private static DataSource INSTANCE; + + public static DataSource getInstance() { + if (Objects.isNull(INSTANCE)) { + INSTANCE = createJdbcDataSource(); + } + return INSTANCE; + } + + private static JdbcDataSource createJdbcDataSource() { + final JdbcDataSource jdbcDataSource = new JdbcDataSource(); + jdbcDataSource.setUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;"); + jdbcDataSource.setUser(""); + jdbcDataSource.setPassword(""); + return jdbcDataSource; + } + + private DataSourceConfig() { + } +} diff --git a/jdbc/src/test/java/nextstep/jdbc/DatabasePopulatorUtils.java b/jdbc/src/test/java/nextstep/jdbc/DatabasePopulatorUtils.java new file mode 100644 index 0000000000..bf9b9c9630 --- /dev/null +++ b/jdbc/src/test/java/nextstep/jdbc/DatabasePopulatorUtils.java @@ -0,0 +1,33 @@ +package nextstep.jdbc; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.sql.DataSource; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +public class DatabasePopulatorUtils { + + private static final Logger log = LoggerFactory.getLogger(DatabasePopulatorUtils.class); + + public static void execute(DataSource dataSource) { + try (Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement()) { + final URL url = DatabasePopulatorUtils.class.getClassLoader().getResource("schema.sql"); + final File file = new File(url.getFile()); + final String sql = Files.readString(file.toPath()); + statement.execute(sql); + } catch (NullPointerException | IOException | SQLException e) { + log.error(e.getMessage(), e); + } + } + + private DatabasePopulatorUtils() { + } +} diff --git a/jdbc/src/test/java/nextstep/jdbc/JdbcTemplateTest.java b/jdbc/src/test/java/nextstep/jdbc/JdbcTemplateTest.java index 040f689480..18b93644c4 100644 --- a/jdbc/src/test/java/nextstep/jdbc/JdbcTemplateTest.java +++ b/jdbc/src/test/java/nextstep/jdbc/JdbcTemplateTest.java @@ -1,5 +1,56 @@ package nextstep.jdbc; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + class JdbcTemplateTest { -} \ No newline at end of file + private JdbcTemplate jdbcTemplate; + private RowMapper userRowMapper; + + @BeforeEach + void setUp() { + DatabasePopulatorUtils.execute(DataSourceConfig.getInstance()); + jdbcTemplate = new JdbcTemplate(DataSourceConfig.getInstance()); + userRowMapper = userRowMapper = rs -> new User( + rs.getLong("id"), + rs.getString("account"), + rs.getString("password"), + rs.getString("email")); + + String sql = "insert into users (account, password, email) values (?, ?, ?)"; + jdbcTemplate.update(sql, "bepoz", "1234", "bepoz@jdbc.ocm"); + } + + @Test + @DisplayName("update Test") + void updateCountTest() { + String sql = "insert into users (account, password, email) values (?, ?, ?)"; + int rowCount = jdbcTemplate.update(sql, "gump", "1234", "gump@jdbc.com"); + + assertThat(rowCount).isEqualTo(1); + } + + @Test + @DisplayName("queryForObject Test") + public void queryforObjectTest() { + String sql = "select id, account, password, email from users where id = 1"; + User user = jdbcTemplate.queryForObject(sql, userRowMapper); + + assertThat(user).isEqualTo(new User(1L, "bepoz", "1234", "bepoz@jdbc.com")); + } + + @Test + @DisplayName("query Test") + public void queryTest() { + String sql = "select id, account, password, email from users"; + List users = jdbcTemplate.query(sql, userRowMapper); + + assertThat(users).containsExactlyInAnyOrder(new User(1L, "bepoz", "1234", "bepoz@jdbc.com")); + } +} diff --git a/jdbc/src/test/java/nextstep/jdbc/User.java b/jdbc/src/test/java/nextstep/jdbc/User.java new file mode 100644 index 0000000000..71c2144fbd --- /dev/null +++ b/jdbc/src/test/java/nextstep/jdbc/User.java @@ -0,0 +1,71 @@ +package nextstep.jdbc; + +import java.util.Objects; + +public class User { + + private Long id; + private final String account; + private String password; + private final String email; + + public User(long id, String account, String password, String email) { + this.id = id; + this.account = account; + this.password = password; + this.email = email; + } + + public User(String account, String password, String email) { + this.account = account; + this.password = password; + this.email = email; + } + + public boolean checkPassword(String password) { + return this.password.equals(password); + } + + public void changePassword(String password) { + this.password = password; + } + + public String getAccount() { + return account; + } + + public long getId() { + return id; + } + + public String getEmail() { + return email; + } + + public String getPassword() { + return password; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + User user = (User) o; + return Objects.equals(id, user.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + return "User{" + + "id=" + id + + ", account='" + account + '\'' + + ", email='" + email + '\'' + + ", password='" + password + '\'' + + '}'; + } +} diff --git a/jdbc/src/test/resources/logback.xml b/jdbc/src/test/resources/logback.xml new file mode 100644 index 0000000000..c127b484d4 --- /dev/null +++ b/jdbc/src/test/resources/logback.xml @@ -0,0 +1,15 @@ + + + + + + %d{HH:mm:ss.SSS} [%-5level] [%thread] [%logger{36}] - %m%n + + + + + + + + + diff --git a/jdbc/src/test/resources/schema.sql b/jdbc/src/test/resources/schema.sql new file mode 100644 index 0000000000..1bfb704f61 --- /dev/null +++ b/jdbc/src/test/resources/schema.sql @@ -0,0 +1,7 @@ +create table if not exists users ( + id bigint auto_increment, + account varchar(100) not null, + password varchar(100) not null, + email varchar(100) not null, + primary key(id) +); diff --git a/learning/src/test/java/servlet/ServletTest.java b/learning/src/test/java/servlet/ServletTest.java index cb23cefb1f..0f1ee8a52b 100644 --- a/learning/src/test/java/servlet/ServletTest.java +++ b/learning/src/test/java/servlet/ServletTest.java @@ -18,7 +18,7 @@ class ServletTest { /** * 2. 톰캣 maxThread 테스트 가능할까? - * + *

* 서블릿 컨테이너 설정 테스트 코드 * accept-count 1 * threads max 1 diff --git a/mvc/src/main/java/nextstep/mvc/HandlerAdapter.java b/mvc/src/main/java/nextstep/mvc/HandlerAdapter.java index b1666cb54e..40348b5f2d 100644 --- a/mvc/src/main/java/nextstep/mvc/HandlerAdapter.java +++ b/mvc/src/main/java/nextstep/mvc/HandlerAdapter.java @@ -1,9 +1,8 @@ package nextstep.mvc; -import nextstep.mvc.view.ModelAndView; - import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import nextstep.mvc.view.ModelAndView; public interface HandlerAdapter { boolean supports(Object handler); diff --git a/mvc/src/main/java/nextstep/mvc/HandlerMappingRegistry.java b/mvc/src/main/java/nextstep/mvc/HandlerMappingRegistry.java index 118cead076..e8b151e4bd 100644 --- a/mvc/src/main/java/nextstep/mvc/HandlerMappingRegistry.java +++ b/mvc/src/main/java/nextstep/mvc/HandlerMappingRegistry.java @@ -1,6 +1,7 @@ package nextstep.mvc; import jakarta.servlet.http.HttpServletRequest; + import java.util.ArrayList; import java.util.List; import java.util.Objects; diff --git a/mvc/src/main/java/nextstep/mvc/view/util/ViewRedirectHelper.java b/mvc/src/main/java/nextstep/mvc/view/util/ViewRedirectHelper.java new file mode 100644 index 0000000000..872a66e4b9 --- /dev/null +++ b/mvc/src/main/java/nextstep/mvc/view/util/ViewRedirectHelper.java @@ -0,0 +1,14 @@ +package nextstep.mvc.view.util; + +import nextstep.mvc.view.JspView; +import nextstep.mvc.view.ModelAndView; + +public class ViewRedirectHelper { + + private ViewRedirectHelper() { + } + + public static ModelAndView redirect(String path) { + return new ModelAndView(new JspView(JspView.REDIRECT_PREFIX + path)); + } +}