이전에 했던 프로젝트를 JdbcTemplate 리팩토링하여 기존의 코드를 좀 더 간단히 출력하고 최종 형식을 맞춘 JDBC 쿼리문을 만들어 보겠다.
이전 프로젝트 : https://velog.io/@qowl880/Spring-Spring%EC%97%90%EC%84%9C-Query%EB%AC%B8-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%813
DAO객체에서 DB와 연동하기 위해 SQL 연산들을 수행 할 수 있도록 도와주는 기술이다
스프링에서 JDBC를 이용하는 DAO에서 사용할수있도록 템플릿/콜백 기술을 제공한다
생성자의 파라미터로 dataSource를 사용한다
JdbcTemplate이 JdbcContext를 완전히 대체 가능하며 JDBC를 매우 편하게 사용할 수 있다.
UserDao 생성자 초기화
private JdbcTemplate jdbcTemplate;
public UserDao(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
deleteAll 메서드
public void deleteAll() throws SQLException {
this.jdbcTemplate.update("delete from users");
}
add 메서드
public void add(final User user) throws SQLException {
this.jdbcTemplate.update("insert into users(id, name, password) values (?, ?, ?);",
user.getId(), user.getName(), user.getPassword());
}
update( )
- executeSql( )과 기능이 비슷한 메서드
- SQL연산을 통해 데이터베이스를 갱신시켜줄때(INSERT,DELETE,UPDATE)사용하는 메서드이다.
getCount 메서드
public int getCount() throws SQLException {
return this.jdbcTemplate.queryForObject("select count(*) from users;", Integer.class);
}
queryforObject( )
- SELECT를 실행했을 때 하나의 객체(Object) 결과 값이 나올 때 사용하는 메소드이다.
- 결과로 단일 행을 받는 대신, 만약 0 또는 1 초과의 행이 반환 되면 에러를 발생 시킨다.
- getCount()에 적용했던 RowMapper 콜백을 사용해줘야 한다.
findById 메서드
public User findById(String id) {
String sql = "select * from users where id = ?";
RowMapper<User> rowMapper = new RowMapper<User>() {
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User(rs.getString("id"), rs.getString("name"),
rs.getString("password"));
return user;
}
};
return this.jdbcTemplate.queryForObject(sql, rowMapper, id);
}
getAll 메서드
public List<User> getAll() {
String sql = "select * from users order by id";
RowMapper<User> rowMapper = new RowMapper<User>() {
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User(rs.getString("id"), rs.getString("name"),
rs.getString("password"));
return user;
}
};
return this.jdbcTemplate.query(sql, rowMapper);
}
RowMapper
- 원하는 객체로 타입을 변환하는 역할이다.
- queryForObject의 반환형은 데이터형만 가능 하지만, SELECT로 나온 여러개의 값을 반환 할 수 있을 뿐만 아니라, 사용자가 원하는 형태로도 얼마든지 받을 수 있다.
RowMapper<User> rowMapper = new RowMapper<User>() {
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User(rs.getString("id"), rs.getString("name"),
rs.getString("password"));
return user;
}
};
public User findById(String id) {
String sql = "select * from users where id = ?";
return this.jdbcTemplate.queryForObject(sql, rowMapper, id);
}
public List<User> getAll() {
String sql = "select * from users order by id";
return this.jdbcTemplate.query(sql, rowMapper);
}
클래스이름 | Context | 전략 | 선택 전략 | 사용 방법 |
---|---|---|---|---|
UserDao | .add(), .findById() | ConnectionMaker | AwsConnectionMaker LocalConnectionMaker TeacherConnectionMaker | 중복코드 분리 및 DB별 구현체 필요에 따라 사용 |
Factory | awsConnection() | UserFactory | awsConnection | ConnectionMaker와 DAO를 연결시켜주는 역할, 필요한 ConnectionMaker를 추가시키기 위해서 |
Strategy | .deleteAll() | StatementStrategy | DeleteAllStrategy AddStrategy | SQL 쿼리문 별도 분리 interface를 의존하게하여 구현체를 필요에 따라 사용 |
DataSource | Connection -> DataSource | DataSource | awsDataSource | Connection을 DataSource 인터페이스로 변경하였다. 따라서, ConnectionMaker는 더이상 필요하지 않다. Factory클래스에 한번에 작성함 |
JdbcTemplate | DAO 메서드 전부 | JdbcTemplate | update() queryforObject( ) RowMapper | 자바 내에 있는 JdbcTemplate 인터페이스를 사용하여 Context -> JdbcTample로 사용 그동안 작성한 코드를 한줄로 사용 |