JdbcTemplate 사용 및 람다식으로 축약하기
2022. 1. 17. 19:49ㆍ북리뷰/토비의 봄
728x90
이전 포스팅에서 템플릿과 콜백의 기본적인 원리와 동작방식, 만드는 방법에 대해 알아보았다. 스프링에도 JDBC를 이용하는 DAO에서 사용할 수 있도록 다양한 템플릿과 콜백을 제공한다.
스프링에서 제공하는 JDBC 코드용 기본 템플릿은 JdbcTemplate이다. 한번 사용해보자
public class UserDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
...
}
update()
update() 메서드는 PreparedStatementCreator타입을 콜백 받아서 사용한다. 다음과 같이 사용하면 된다
public class UserDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public void add(User user) {
this.jdbcTemplate.update("insert into users(id, name, password) values (?,?,?)",
user.getId(), user.getName(), user.getPassword());
}
public void deleteAll() {
this.jdbcTemplate.update("delete from users");
}
...
}
queryForObject()
만약 select문 같이 결과 값을 가져와야 하는 SQL쿼리는 어떻게 처리할까? queryForObject() 메서드를 사용하면 된다. 이 메서드는 ResultSet을 전달받는 RowMapper을 콜백으로 전달받는다.
public class UserDao {
public User get(String id) {
return this.jdbcTemplate.queryForObject("select * from users where id = ?",
new Object[]{id},
new RowMapper<User>() {
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setId(rs.getString("id"));
user.setName(rs.getString("name"));
user.setPassword(rs.getString("password"));
return user;
}
});
}
public int getCount() {
return this.jdbcTemplate.queryForObject("select count(*) from users", Integer.class);
}
...
}
query()
RowMapper을 좀 더 사용해보자. 현재 등록되어 있는 모든 사용자 정보를 리스트 형태로 가져오는 getAll() 메서드를 추가해보자. 메서드를 제작하기 전에 테스트코드를 우선 제작해보자.
@Test
public void getAll() {
dao.deleteAll();
List<User> users0 = dao.getAll();
assertThat(users0.size(), is(0));
dao.add(user1);
List<User> users1 = dao.getAll();
assertThat(users1.size(), is(1));
checkSameUser(user1, users1.get(0));
dao.add(user2);
List<User> users2 = dao.getAll();
assertThat(users2.size(), is(2));
checkSameUser(user1, users2.get(0));
checkSameUser(user2, users2.get(1));
dao.add(user3);
List<User> users3 = dao.getAll();
assertThat(users3.size(), is(3));
checkSameUser(user1, users3.get(0));
checkSameUser(user2, users3.get(1));
checkSameUser(user3, users3.get(2));
}
이제 테스트를 성공시키는 getAll() 메서드를 제작해보자
public class UserDao {
public List<User> getAll() {
return this.jdbcTemplate.query("select * from users order by id",
new RowMapper<User>() {
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setId(rs.getString("id"));
user.setName(rs.getString("name"));
user.setPassword(rs.getString("password"));
return user;
}
});
}
...
}
중복 제거
get()과 getAll()을 보면 겹치는 부분이 있다.
new RowMapper<User>() {
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setId(rs.getString("id"));
user.setName(rs.getString("name"));
user.setPassword(rs.getString("password"));
return user;
}
}
바로 이 부분이다. 이 부분을 따로 변수로 빼서 사용하도록 하자.
public class UserDao {
private JdbcTemplate jdbcTemplate;
private RowMapper<User> userRowMapper =
new RowMapper<User>() {
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setId(rs.getString("id"));
user.setName(rs.getString("name"));
user.setPassword(rs.getString("password"));
return user;
}
};
public void setJdbcTemplate(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public User get(String id) {
return this.jdbcTemplate.queryForObject("select * from users where id = ?",
new Object[]{id}, this.userRowMapper);
}
public List<User> getAll() {
return this.jdbcTemplate.query("select * from users order by id", this.userRowMapper);
}
...
}
람다식 활용
위 코드들을 람다식을 활용하면 코드를 더 간소화 시킬 수 있다.
public class UserDao {
private JdbcTemplate jdbcTemplate;
private RowMapper<User> userRowMapper =
(rs, rowNum) -> new User(rs.getString("id"),
rs.getString("name"),
rs.getString("password"));
public void setJdbcTemplate(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public void add(User user) {
this.jdbcTemplate.update("insert into users(id, name, password) values (?,?,?)",
user.getId(), user.getName(), user.getPassword());
}
public User get(String id) {
return this.jdbcTemplate.queryForObject("select * from users where id = ?",
new Object[]{id}, this.userRowMapper);
}
public void deleteAll() {
this.jdbcTemplate.update("delete from users");
}
public int getCount() {
return this.jdbcTemplate.queryForObject("select count(*) from users", Integer.class);
}
public List<User> getAll() {
return this.jdbcTemplate.query("select * from users order by id", this.userRowMapper);
}
}
728x90
'북리뷰 > 토비의 봄' 카테고리의 다른 글
Spring Web MVC web.xml 분석 (0) | 2022.01.30 |
---|---|
템플릿/콜백 패턴 예시, 익명 클래스를 람다식으로 변환 (0) | 2022.01.17 |
중첩클래스와 익명 클래스로 클래스 파일 간소화 (0) | 2022.01.17 |
try/catch/finally로 예외 처리 및 전략 패턴으로 중복 컨텍스트 추출 (1) | 2022.01.16 |
JUnit @Before(@After)사용으로 테스트 코드 중복 제거 및 스프링 테스트 적용 (0) | 2022.01.16 |