A factory for connections to the physical data source that this DataSource object represents.
Basic implementation -- produces a standard Connection object
Connection pooling implementation -- produces a Connection object that will automatically participate in connection pooling. This implementation works with a middle-tier connection pooling manager.
Distributed transaction implementation -- produces a Connection object that may be used for distributed transactions and almost always participates in connection pooling. This implementation works with a middle-tier transaction manager and almost always with a connection pooling manager.
JdbcTemplate
를 활용하여 조회 쿼리를 실행해보자, jdbc를 활용하기 위해서는 아래와 같이 선언을 한다
private final JdbcTemplate jdbcTemplate;
@Autowired // 생성자 선언 - datasource를 spring이 넣어준다 (현재 h2 DB의 위치url이다)
public JdbcTemplateMemberRepository(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
JdbcTemplate는 SELECT 쿼리문을 위한 query()메소드를 제공한다
- List<\T> query(String sql, RowMapper<\T> rowMapper)
- List<\T> query(String sql, Object [] args, RowMapper<\T> rowMapper)
- List<\T> query(String sql, RowMapper<\T> rowMapper, Object... args)
참고
query() 메소드는 파라미터의 sql을 실행하고, 결과로 나온 ResultSet을 RowMapper가 JAVA의 객체로 변환한다. 그리고 sql 파라미터가 인덱스 기반 파라미터를 가진 쿼리(preparedStatement의 물음)인 경우, 각 파라미터의 값을 args로 지정한다
private RowMapper<Member> memberRowMapper() {
//람다식 표현
return (resultSet, rowNum) -> {
Member member = new Member();
member.setId(resultSet.getLong("id"));
member.setName(resultSet.getString("name"));
return member;
};
//내부 익명 클래스
return new RowMapper<Member>() {
@Override
public Member mapRow(ResultSet resultSet, int rowNum) throws SQLException {
Member member = new Member();
member.setId(resultSet.getLong("id"));
member.setName(resultSet.getString("name"));
return member;
}
};
}
public class JdbcTemplateMemberRepository implements MemberRepository{
private final JdbcTemplate jdbcTemplate;
@Autowired
public JdbcTemplateMemberRepository(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public Member save(Member member) {
SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
jdbcInsert.withTableName("member").usingGeneratedKeyColumns("id");
Map<String, String> parameters = new HashMap<>();
parameters.put("name", member.getName());
Number key = jdbcInsert.executeAndReturnKey(new MapSqlParameterSource(parameters));
member.setId(key.longValue());
return member;
}
@Override
public Optional<Member> findById(Long id) {
List<Member> result = jdbcTemplate.query("select * from member where id = ?", memberRowMapper(), id);
return result.stream().findAny();
}
@Override
public Optional<Member> findByName(String name) {
List<Member> result = jdbcTemplate.query("slect * from member where name = ?", memberRowMapper(), name);
return result.stream().findAny();
}
@Override
public List<Member> findAll() {
return jdbcTemplate.query("select * from member", memberRowMapper());
}
private RowMapper<Member> memberRowMapper() {
return (resultSet, rowNum) -> {
Member member = new Member();
member.setId(resultSet.getLong("id"));
member.setName(resultSet.getString("name"));
return member;
};
}
}
이제 @Configuration에서 이 JdbcTemplate를 사용하도록 변경하면 된다
@Bean
public MemberRepository memberRepository()
{
//return new MemoryMemberRepository();
//return new JdbcMemberRepository(dataSource);
return new JdbcTemplateMemberRepository(dataSource);
}