스프링 JdbcTemplate에 대해서 알아보자.
스프링 JdbcTemplate과 MyBatis 같은 라이브러리는 JDBC API에서 본 반복 코드를 대부분 제거해준다. 하지만 SQL은 직접 작성해야 한다.
사용방법은 아래와같다.
생성자가 하나라면 @Autowired 생략 가능하다.
private final JdbcTemplate jdbcTemplate;
@Autowired
private JdbcTemplateMemberRepository(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
findById 부터 구현해보자. 결과가 나오는것을 RowMapper로 매핑해줘야 한다.
@Override
public Optional<Member> findById(Long id) {
List<Member> result = jdbcTemplate.query("select * from member where id = ?",);
}
아래에 생성
private RowMapper<Member> memberRowMapper() {
return new RowMapper<Member>() {
@Override
public Member mapRow(ResultSet rs, int rowNum) throws SQLException {
Member member = new Member();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
return member;
}
}
}
람다로 변경이 가능하다.
private RowMapper<Member> memberRowMapper() {
return (rs, rowNum) -> {
Member member = new Member();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
return member;
};
}
findById에 두번째 파라미터로 memberRowMapper를 넣어준다.
값을 result로 뽑아주고 stream()과 findAny() 메서드를 활용하여 값을 return 해준다.
@Override
public Optional<Member> findById(Long id) {
List<Member> result = jdbcTemplate.query("select * from member where id = ?", memberRowMapper());
return result.stream().findAny();
}
순수 JDBC와 비교했을때 코드가 엄청 간결해졌다.
sava 구현
SimpleJdbcInsert를 활용하면 쿼리를 짤 필요가없어진다.
@Override
public Member save(Member member) {
SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
jdbcInsert.withTableName("member").usingGeneratedKeyColumns("id");
Map<String, Object> parameters = new HashMap<>();
parameters.put("name", member.getName());
Number key = jdbcInsert.executeAndReturnKey(new MapSqlParameterSource(parameters));
member.setId(key.longValue());
return member;
}
findByName 구현
@Override
public Optional<Member> findByName(String name) {
List<Member> result = jdbcTemplate.query("select * from member where name = ?", memberRowMapper(), name);
return result.stream().findAny();
}
findAll 구현
@Override
public List<Member> findAll() {
return jdbcTemplate.query("select * from member", memberRowMapper());
}
코드 전부 변경후 SprigConfig 파일가서 다시 조립해보자.
이번에는 JdbcTemplateMemberRepository를 리턴해준다.
package hello.hellospring;
import hello.hellospring.repository.JdbcMemberRepository;
import hello.hellospring.repository.JdbcTemplateMemberRepository;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class SpringConfig {
private DataSource dataSource;
@Autowired
public SpringConfig(DataSource dataSource) {
this.dataSource = dataSource;
}
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
//return new MemoryMemberRepository();
//return new JdbcMemberRepository(dataSource);
return new JdbcTemplateMemberRepository(dataSource);
}
}
통합 테스트를 만들어놨기에 테스트 코드로 문제가 없나 확인이 가능하다.
테스트가서 테스트를 해보면 회원가입에서 에러발생!
id가 매핑이 안되어있었다. 코드 수정 후 다시 테스트해보면 성공한다.