-
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단계] 제나(위예나) 미션 제출합니다 #317
Changes from 9 commits
dc70d1d
7182a49
04ff160
b8b1923
229e98e
45dfde4
cb652e9
6de5b9b
f873039
ea09753
e0065b4
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,8 @@ | ||
# JDBC 라이브러리 구현하기 | ||
|
||
## 1단계 | ||
- [x] UserDaoTest 성공시키기 | ||
- [x] update() | ||
- [x] findAll() | ||
- [x] findByAccount() | ||
- [x] 중복 코드는 JdbcTemplate 에 추출하기 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,18 +5,21 @@ | |
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 static org.assertj.core.api.Assertions.assertThat; | ||
|
||
class UserDaoTest { | ||
|
||
private UserDao userDao; | ||
private JdbcTemplate jdbcTemplate; | ||
|
||
@BeforeEach | ||
void setup() { | ||
DatabasePopulatorUtils.execute(DataSourceConfig.getInstance()); | ||
jdbcTemplate = new JdbcTemplate(DataSourceConfig.getInstance()); | ||
|
||
userDao = new UserDao(DataSourceConfig.getInstance()); | ||
userDao = new UserDao(jdbcTemplate); | ||
final var user = new User("gugu", "password", "[email protected]"); | ||
userDao.insert(user); | ||
} | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -4,6 +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; | ||||||
import java.util.ArrayList; | ||||||
import java.util.List; | ||||||
|
||||||
public class JdbcTemplate { | ||||||
|
||||||
|
@@ -14,4 +20,195 @@ public class JdbcTemplate { | |||||
public JdbcTemplate(final DataSource dataSource) { | ||||||
this.dataSource = dataSource; | ||||||
} | ||||||
|
||||||
public Connection getConnection() throws SQLException { | ||||||
return dataSource.getConnection(); | ||||||
} | ||||||
|
||||||
public void execute(String sql) { | ||||||
context(new PreparedStrategy() { | ||||||
@Override | ||||||
public PreparedStatement createStatement(Connection connection) throws SQLException { | ||||||
return connection.prepareStatement(sql); | ||||||
} | ||||||
}); | ||||||
Comment on lines
+29
to
+34
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 void execute(String sql, Object... args) { | ||||||
context(new PreparedStrategy() { | ||||||
@Override | ||||||
public PreparedStatement createStatement(Connection connection) throws SQLException { | ||||||
return connection.prepareStatement(sql); | ||||||
} | ||||||
}, args); | ||||||
} | ||||||
|
||||||
public <T> List<T> query(String sql, RowMapper<T> rm) { | ||||||
return context(new PreparedStrategy() { | ||||||
@Override | ||||||
public PreparedStatement createStatement(Connection connection) throws SQLException { | ||||||
return connection.prepareStatement(sql); | ||||||
} | ||||||
}, rm); | ||||||
} | ||||||
|
||||||
public <T> T queryForObject(String sql, RowMapper<T> rm, Object... args) { | ||||||
List<T> list = context(new PreparedStrategy() { | ||||||
@Override | ||||||
public PreparedStatement createStatement(Connection connection) throws SQLException { | ||||||
return connection.prepareStatement(sql); | ||||||
} | ||||||
}, rm, args); | ||||||
|
||||||
if (list.isEmpty()) { | ||||||
return null; | ||||||
} | ||||||
return list.get(0); | ||||||
Comment on lines
+63
to
+66
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. list에 값이 여러개 들어있는 경우에도 첫 번째 값만 반환하도록 의도한게 맞을까요 ?!
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. queryForObject 는 하나의 Object 만 반환하기를 예상하고 사용하는 메서드라서 두개 이상의 값이 list 에 들어가면 예외를 반환하게끔 수정해봤어요! |
||||||
} | ||||||
|
||||||
public void context(PreparedStrategy preparedStrategy) { | ||||||
Connection conn = null; | ||||||
PreparedStatement pstmt = null; | ||||||
try { | ||||||
conn = dataSource.getConnection(); | ||||||
pstmt = preparedStrategy.createStatement(conn); | ||||||
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) { | ||||||
} | ||||||
} | ||||||
Comment on lines
+70
to
+93
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. 적용하니까 코드가 너무 깔끔해졌어요 👍 |
||||||
} | ||||||
|
||||||
public void context(PreparedStrategy preparedStrategy, Object[] args) { | ||||||
Connection conn = null; | ||||||
PreparedStatement pstmt = null; | ||||||
try { | ||||||
conn = dataSource.getConnection(); | ||||||
pstmt = preparedStrategy.createStatement(conn); | ||||||
|
||||||
for (int i = 0; i < args.length; i++) { | ||||||
pstmt.setObject(i + 1, args[i]); | ||||||
} | ||||||
|
||||||
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) { | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
public <T> List<T> context(PreparedStrategy preparedStrategy, RowMapper<T> rm) { | ||||||
Connection conn = null; | ||||||
PreparedStatement pstmt = null; | ||||||
ResultSet rs = null; | ||||||
try { | ||||||
conn = dataSource.getConnection(); | ||||||
pstmt = preparedStrategy.createStatement(conn); | ||||||
rs = pstmt.executeQuery(); | ||||||
|
||||||
ArrayList<T> list = new ArrayList<>(); | ||||||
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.
Suggested change
인터페이스에 대고 프로그래밍하기 ! 에 대해서는 어떻게 생각하시나용 🧐 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. 오 넘 좋습니다!! |
||||||
while (rs.next()) { | ||||||
list.add(rm.mapRow(rs)); | ||||||
} | ||||||
return list; | ||||||
} 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 <T> List<T> context(PreparedStrategy preparedStrategy, RowMapper<T> rm, Object[] args) { | ||||||
Connection conn = null; | ||||||
PreparedStatement pstmt = null; | ||||||
ResultSet rs = null; | ||||||
try { | ||||||
conn = dataSource.getConnection(); | ||||||
pstmt = preparedStrategy.createStatement(conn); | ||||||
|
||||||
for (int i = 0; i < args.length; i++) { | ||||||
pstmt.setObject(i + 1, args[i]); | ||||||
} | ||||||
|
||||||
rs = pstmt.executeQuery(); | ||||||
|
||||||
ArrayList<T> list = new ArrayList<>(); | ||||||
while (rs.next()) { | ||||||
list.add(rm.mapRow(rs)); | ||||||
} | ||||||
return list; | ||||||
} 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) { | ||||||
} | ||||||
} | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package org.springframework.jdbc.core; | ||
|
||
import java.sql.Connection; | ||
import java.sql.PreparedStatement; | ||
import java.sql.SQLException; | ||
|
||
public interface PreparedStrategy { | ||
|
||
PreparedStatement createStatement(Connection connection) 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.
람다 표현식을 사용해서 코드를 조금 더 간소화 할 수 있을 것 같아요 !!
UserDao 내부에서만 사용된다면
private
으로 관리하는건 어떨까요 !?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.
접근제어자 신경을 안썼엇네요!! 감사합니당
람다로도 바꿔봤어요 ㅎㅎ