-
Notifications
You must be signed in to change notification settings - Fork 300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[JDBC 라이브러리 구현하기 - 1단계] 허브(방대의) 미션 제출합니다. #267
Changes from 3 commits
dc70d1d
7182a49
06379e5
d92089d
c4ae60a
e4f4b39
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,6 @@ | ||
# JDBC 라이브러리 구현하기 | ||
|
||
### 1단계 - JDBC 라이브러리 구현하기 | ||
|
||
- [x] RowMapper 인터페이스를 추가한다. | ||
- [x] JdbcTemplate으로 코드 이동시킨다. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,121 +1,52 @@ | ||
package com.techcourse.dao; | ||
|
||
import com.techcourse.domain.User; | ||
import org.springframework.jdbc.core.JdbcTemplate; | ||
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; | ||
import javax.sql.DataSource; | ||
import org.springframework.jdbc.core.JdbcTemplate; | ||
import org.springframework.jdbc.core.RowMapper; | ||
|
||
public class UserDao { | ||
|
||
private static final Logger log = LoggerFactory.getLogger(UserDao.class); | ||
private static final RowMapper<User> USER_ROW_MAPPER = (resultSet) -> new User( | ||
resultSet.getLong(1), | ||
resultSet.getString(2), | ||
resultSet.getString(3), | ||
resultSet.getString(4) | ||
); | ||
|
||
private final DataSource dataSource; | ||
private final JdbcTemplate jdbcTemplate; | ||
|
||
public UserDao(final DataSource dataSource) { | ||
this.dataSource = dataSource; | ||
this.jdbcTemplate = new JdbcTemplate(dataSource); | ||
} | ||
|
||
public UserDao(final JdbcTemplate jdbcTemplate) { | ||
this.dataSource = null; | ||
this.jdbcTemplate = jdbcTemplate; | ||
} | ||
|
||
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) {} | ||
} | ||
final String sql = "insert into users (account, password, email) values (?, ?, ?)"; | ||
jdbcTemplate.update(sql, user.getAccount(), user.getPassword(), user.getEmail()); | ||
} | ||
|
||
public void update(final User user) { | ||
// todo | ||
final String sql = "update users set (account, password, email) = (?, ?, ?) where id = ?"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 앗 이렇게도 묶어서 되는거였군요..! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 박스터한테 배웠습니다 ㅋㅋㅋㅋ |
||
jdbcTemplate.update(sql, user.getAccount(), user.getPassword(), user.getEmail(), user.getId()); | ||
} | ||
|
||
public List<User> findAll() { | ||
// todo | ||
return null; | ||
final String sql = "select id, account, password, email from users"; | ||
return jdbcTemplate.queryForList(sql, USER_ROW_MAPPER); | ||
} | ||
|
||
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) {} | ||
|
||
try { | ||
if (conn != null) { | ||
conn.close(); | ||
} | ||
} catch (SQLException ignored) {} | ||
} | ||
final String sql = "select id, account, password, email from users where id = ?"; | ||
return jdbcTemplate.queryForObject(sql, USER_ROW_MAPPER, id); | ||
} | ||
|
||
public User findByAccount(final String account) { | ||
// todo | ||
return null; | ||
final String sql = "select id, account, password, email from users where account = ?"; | ||
return jdbcTemplate.queryForObject(sql, USER_ROW_MAPPER, account); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,15 @@ | ||
package org.springframework.jdbc.core; | ||
|
||
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 javax.sql.DataSource; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import javax.sql.DataSource; | ||
|
||
public class JdbcTemplate { | ||
|
||
private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class); | ||
|
@@ -14,4 +19,61 @@ public class JdbcTemplate { | |
public JdbcTemplate(final DataSource dataSource) { | ||
this.dataSource = dataSource; | ||
} | ||
|
||
public void update(final String sql, final Object... parameters) { | ||
try (final Connection connection = dataSource.getConnection(); | ||
final PreparedStatement preparedStatement = getPreparedStatement(sql, connection, parameters)) { | ||
log.debug("query : {}", sql); | ||
for (int i = 0; i < parameters.length; i++) { | ||
preparedStatement.setObject(i + 1, parameters[i]); | ||
} | ||
preparedStatement.executeUpdate(); | ||
} catch (SQLException e) { | ||
log.error(e.getMessage(), e); | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
public <T> T queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) { | ||
try (final Connection connection = dataSource.getConnection(); | ||
final PreparedStatement preparedStatement = getPreparedStatement(sql, connection, parameters); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그저 감탄입니다... 허브센세...ㅠㅠ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. try with resources 정말 깔끔합니다 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 준팍센세.. 반갑습니다 ✋ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 와우,,,, 퍼가요@@@@ |
||
final ResultSet resultSet = preparedStatement.executeQuery()) { | ||
log.debug("query : {}", sql); | ||
if (resultSet.next()) { | ||
return rowMapper.mapRow(resultSet); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 만약 쿼리 실행 결과가 하나가 아니면 어떻게 되는걸까여?! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 하나면 조회 결과 중 제일 처음 부분만 반환될 것 같습니다! |
||
} | ||
return null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 호옥시 null을 반환하는 허브의 기준이 있을까유?! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 일단 UserDaoTest를 수정하지 않고 동작하게 하려고 null을 반환시켰습니다! |
||
} catch (SQLException e) { | ||
log.error(e.getMessage(), e); | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
private PreparedStatement getPreparedStatement( | ||
final String sql, | ||
final Connection connection, | ||
final Object[] parameters | ||
) throws SQLException { | ||
final PreparedStatement preparedStatement = connection.prepareStatement(sql); | ||
for (int i = 0; i < parameters.length; i++) { | ||
preparedStatement.setObject(i + 1, parameters[i]); | ||
} | ||
return preparedStatement; | ||
} | ||
|
||
public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) { | ||
try (final Connection connection = dataSource.getConnection(); | ||
final PreparedStatement preparedStatement = getPreparedStatement(sql, connection, parameters); | ||
final ResultSet resultSet = preparedStatement.executeQuery()) { | ||
log.debug("query : {}", sql); | ||
final List<T> result = new ArrayList<>(); | ||
while (resultSet.next()) { | ||
result.add(rowMapper.mapRow(resultSet)); | ||
} | ||
return result; | ||
} catch (SQLException e) { | ||
log.error(e.getMessage(), e); | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package org.springframework.jdbc.core; | ||
|
||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
|
||
@FunctionalInterface | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
public interface RowMapper<T> { | ||
|
||
T mapRow(ResultSet resultSet) throws SQLException; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!!
허브는 기능 명세 작성할 때부터 RowMapper를 사용해야겠다는 걸 알고 계셨나요?!
(저는 처음에 Reflection으로 sql의 파라미터수에 맞는 생성자를 찾아서 일일히 타입 맞춰서 넣어주는 건 줄 알고..;; ㅋ)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아하 예전에 체스 미션할 때 JdbcTemplate을 간단하게 만들어본 적이 있어서 기억이 났어요!