create table member
(
id bigint generated by default as identity,
name varchar(255),
primary key (id)
);
insert into member(name) values('spring')
참고 : sql 디렉토리 안에 ddl.sql 파일을 만들어 sql문을 관리
스프링 컨테이너와 DB까지 연결한 통합 테스트이다.
트랜잭션이란? - db의 상태를 변경시키기 위해 수행하는 작업 단위이다. db의 상태를 변경시킨다는 이야기는 SELECT, UPDATE, INSERT, DELETE 와 같은 행동을 뜻한다.
참고로 단위 테스트란 이전에 진행한 순수한 자바 코드로 이루어진 최소한의 단위로 진행하는 테스트이다. 가급적이면 스프링 컨테이너를 올릴 필요 없이 단위단위로 쪼개서 테스트를 진행하는 것이 좋다.
JdbcTemplate과 MyBatis 같은 라이브러리는 순수 JDBC에서의 반복 코드를 대부분
제거해주지만 SQL은 직접 작성해야 한다
build.gradle 파일에 jdbc, h2 데이터베이스 관련 라이브러리 추가
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.h2database:h2'
resources/application.properties에 스프링 부트 데이터베이스 연결 설정 추가
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
JdbcTemplateMemberRepository.java
package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public class JdbcTemplateMemberRepository implements MemberRepository {
@Autowired
public JdbcTemplateMemberRepository(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}
private final JdbcTemplate jdbcTemplate;
@Override
public Member save(Member member) {
//Insert문 생성
SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
jdbcInsert.withTableName("member").usingGeneratedKeyColumns("id");
Map<String, Object> parameters = new HashMap<>();
parameters.put("name", member.getName());
//member id 등록
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(); //Optional로 반환
}
@Override
public Optional<Member> findByName(String name) {
List<Member> result = jdbcTemplate.query("select * from member where name = ?", memberRowMapper());
return result.stream().findAny();
}
@Override
public List<Member> findAll() {
return jdbcTemplate.query("select * from member", memberRowMapper(), name);
}
//데이터베이스의 반환 결과인 ResultSet을 객체(member)로 변환
private RowMapper<Member> memberRowMapper() {
return (rs, rowNum) -> { //결과를 rs에 받음.
Member member = new Member();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
return member;
};
}
}