h2 데이터베이스를 spring에서 데이터베이스로 가져가는 실습을 하면서 spring에서 어떻게 DB를 활용하는 지를 알아보자.
여기서 H2 DB를 다운로드 받는다. 그런 다음 설치를 진행해주고 bin/h2.bat (window)를 실행하면은
위와 같은 화면을 만날 수 있는데 URL을 위와 같이 설정해준다
jdbc:h2:tcp://localhost/~/test
그 다음 연결버튼을 누르면은
위와 같이 DB 콘솔창이 열린다.
drop table if exists member CASCADE;
create table member
(
id bigint generated by default as identity,
name varchar(255),
primary key (id)
);
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.h2database:h2'
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
이전까지 예제에서 Service는 repository interface에 의존한다고 했다. 그리고 db로 interface의 구현체인 memoryMemberRepository를 사용했는데 이제는 jdbc를 이용한 repository를 구현해서 사용해야 한다.
예전에는 JDBC API로 직접 코딩했다.
@Configuration
public class SpringConfig {
private DataSource dataSource;
@Autowired
public SpringConfig(DataSource dataSource) {
this.dataSource = dataSource;
}
@Bean
public MemberRepository memberRepository() {
// return new MemoryMemberRepository();
return new JdbcMemberRepository(dataSource);
}
}
Datasource를 생성자 주입해준다.(Autowired를 이용해서)
public class JdbcMemberRepository implements MemberRepository{
private final DataSource dataSource;
public JdbcMemberRepository(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public Member save(Member member) {
String sql = "insert into member(name) values(?)";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = getConnection();
pstmt = conn.prepareStatement(sql,
Statement.RETURN_GENERATED_KEYS);
pstmt.setString(1, member.getName());
pstmt.executeUpdate();
rs = pstmt.getGeneratedKeys();
if (rs.next()) {
member.setId(rs.getLong(1));
} else {
throw new SQLException("id ");
}
return member;
} catch (Exception e) {
throw new IllegalStateException(e);
} finally {
close(conn, pstmt, rs);
}
}
...
끔찍하다..
그래서 요즘은 jdbc template를 이용해서 코딩을 한다고 한다.
public class JdbcTemplateMemberRepository implements MemberRepository {
private final JdbcTemplate jdbcTemplate;
public JdbcTemplateMemberRepository(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}
@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;
}
...