이전에는 deleteAll()에서 변하지 않는 부분, 자주 변하는 부분을 전략 패턴을 사용해 분리했다.
독립된 JDBC 작업 흐름이 담긴 jdbcContextWithStatementStrategy()는 Dao 메서드들이 공유할 수 있게 되었다.
public void jdbcContextWithStatementStrategy(StatementStrategy statementStrategy) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement;
try{
connection = dataSource.getConnection();
preparedStatement = statementStrategy.makePreparedStatement(connection);
preparedStatement.executeUpdate();
preparedStatement.close();
} finally{
if(connection != null){
connection.close();
}
}
}
Dao 메서드는 전략 패턴의 클라이언트로서 컨텍스트에 해당하는 jdbcContextWithStatementStrategy() 메서드에 적절한 전략을 제공해주는 방법으로 사용할 수 있다.
deleteAll() 말고도 add() 메서드에도 저장해보자.
AddStatement라는 전략 클래스를 또 생성했다.
public class AddStatement implements StatementStrategy {
User user;
public AddStatement(User user) {
this.user = user;
}
@Override
public PreparedStatement makePreparedStatement(Connection c) throws SQLException {
PreparedStatement preparedStatement = c.prepareStatement("insert into users(id, name, password) values (?, ?, ?)");
preparedStatement.setString(1, user.getId());
preparedStatement.setString(2, user.getName());
preparedStatement.setString(3, user.getPassword());
return preparedStatement;
}
}
그리고 UserDao의 add() 메서드도 다음과 같이 수정한다.
public void add(User user) throws SQLException {
StatementStrategy statementStrategy = new AddStatement(user);
jdbcContextWithStatementStrategy(statementStrategy);
}
그리고 일단 테스트를 돌려보니 다음과 같이 성공한다.

자 일단 그럼 여기까지는 성공이다.
지금까지 코드를 더 깔끔하게 만들기는 했지만, 몇가지 문제가 있다.
우선 Dao에서 사용할 메서드마다 StatementStrategy를 구현한 클래스를 만들어야 한다.
또한 add()와 같이 User로 무언가 정보를 넘기는 경우, 이를 해당 구현 클래스의 생성자에 넣어서 전달해야 한다.
이런 문제를 로컬 클래스로 해결가능 할 거 같다.
public void add(User user) throws SQLException {
class AddStatement implements StatementStrategy{
@Override
public PreparedStatement makePreparedStatement(Connection c) throws SQLException {
PreparedStatement ps = c.prepareStatement("insert into users(id, name, password) values(?, ?, ?)");
ps.setString(1, user.getId());
ps.setString(2, user.getName());
ps.setString(3, user.getPassword());
return ps;
}
}
StatementStrategy statementStrategy = new AddStatement();
jdbcContextWithStatementStrategy(statementStrategy);
}
이렇게 add() 메서드 안에 클래스를 만들어서 별도의 클래스 파일을 만들지 않도록 했다.
user 변수에 접근도 가능하기 때문에 추가적으로 생성자에 User를 넘겨줄 필요가 없다.
하지만 이 방법은 진짜 클래스파일을 추가적으로 만들지 않는 것이지, 코드의 작성량은 비슷하다.
그래도 더 간결하게는 만들어보자.
지금 AddStatement는 어차피 내부에서만 사용하기에 이름도 필요 없다.
그냥 익명 내부 클래스로 만들어보자.
public void add(User user) throws SQLException {
StatementStrategy statementStrategy = new StatementStrategy() {
@Override
public PreparedStatement makePreparedStatement(Connection c) throws SQLException {
PreparedStatement ps = c.prepareStatement("insert into users(id, name, password) values(?, ?, ?)");
ps.setString(1, user.getId());
ps.setString(2, user.getName());
ps.setString(3, user.getPassword());
return ps;
}
};
jdbcContextWithStatementStrategy(statementStrategy);
}
이렇게 만들면 더욱 간결하게 코드를 작성할 수 있다.
'백엔드 > 토비의 스프링' 카테고리의 다른 글
[토비의 스프링] 3.5 템플릿과 콜백 (1) | 2025.06.02 |
---|---|
[토비의 스프링] 3.4 컨텍스트와 DI (0) | 2025.05.29 |
[토비의 스프링] 3.2 변하는 것과 변하지 않는 것 (0) | 2025.05.25 |
[토비의 스프링] 3.1 다시 보는 초난감 DAO (0) | 2025.05.21 |
[토비의 스프링] 2.5 학습 테스트로 배우는 스프링 (0) | 2025.05.20 |