Database "C:/Users/사용자명/test" not found, either pre-create it or allow remote database creation (not recommended in secure environments)
jdbc:h2:tcp://localhost/~/test
다음 코드를 넣고 실행시켜 왼쪽에 MEMBER 파일이 생성되었는지 확인한다.
drop table if exists member CASCADE;
create table member
(
id bigint generated by default as identity,
name varchar(255),
primary key (id)
);
다음 코드를 넣고 or member파일을 클릭하고 한번 더 실행한다.
SELECT * FROM MEMBER
확인하기 위해 다음 코드를 넣고 member 파일을 확인해본다.
insert into member(name) values('spring2')
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
이때 오류가 뜨는데 오른쪽에 코끼리 버튼을 누르거나 오른쪽 gradle탭에서 새로고침 모양을 눌러준다.
※ 스프링부트 2.4 버전 이상은 다음 코드를 추가로 넣어주어야 한다.
spring.datasource.username=sa
새로운 구현체인 JdbcMemberRepository 를 만들어주고 다음 코드를 넣는다.
정신건강을 위해 복붙하고 참고만 하도록 하자
package hello.hellospring.repository; import hello.hellospring.domain.Member; import org.springframework.jdbc.datasource.DataSourceUtils; import javax.sql.DataSource; import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.Optional; 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); } } @Override public Optional<Member> findById(Long id) { String sql = "select * from member where id = ?"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql); pstmt.setLong(1, id); rs = pstmt.executeQuery(); if(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); return Optional.of(member); } else { return Optional.empty(); } } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public List<Member> findAll() { String sql = "select * from member"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); List<Member> members = new ArrayList<>(); while(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); members.add(member); } return members; } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public Optional<Member> findByName(String name) { String sql = "select * from member where name = ?"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql); pstmt.setString(1, name); rs = pstmt.executeQuery(); if(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); return Optional.of(member); } return Optional.empty(); } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } private Connection getConnection() { return DataSourceUtils.getConnection(dataSource); } private void close(Connection conn, PreparedStatement pstmt, ResultSet rs) { try { if (rs != null) { rs.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (pstmt != null) { pstmt.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (conn != null) { close(conn); } } catch (SQLException e) { e.printStackTrace(); } } private void close(Connection conn) throws SQLException { DataSourceUtils.releaseConnection(conn, dataSource); } }
- 코드에 대한 자세한 설명은 강의를 참고하도록 하자..
> 강의 사이트
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/dashboard
---
- 이제 우리가 가상 시나리오를 설정하여 구현체를 따로 만들어준 이유를 알 수 있다.
- SpringConfig에서 MemberRepository에게 반환하는 값을 변경해준다.
![](https://velog.velcdn.com/images/jg-konkuk/post/feedce9a-5b87-4c0f-bd45-33251e136380/image.png)
- 또한 위쪽에 다음 코드를 추가해준다.
```java
private final DataSource dataSource;
@Autowired
public SpringConfig(DataSource dataSource) {
this.dataSource = dataSource;
}
이렇게 @Configuration만 만져주면 데이터베이스와 연결된다.
이렇게 구현체를 쉽게 바꾸는 객체지향적인 기술을 스프링이 지원해주기 때문에 스프링을 사용한다.
package hello.hellospring.service;
import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@SpringBootTest
@Transactional
class MemberServiceIntegrationTest {
@Autowired MemberService memberService;
@Autowired MemberRepository memberRepository;
@Test
public void 회원가입() throws Exception {
//Given
Member member = new Member();
member.setName("hello");
//When
Long saveId = memberService.join(member);
//Then
Member findMember = memberRepository.findById(saveId).get();
assertEquals(member.getName(), findMember.getName());
}
@Test
public void 중복_회원_예외() throws Exception {
//Given
Member member1 = new Member();
member1.setName("spring");
Member member2 = new Member();
member2.setName("spring");
//When
memberService.join(member1);
IllegalStateException e = assertThrows(IllegalStateException.class,
() -> memberService.join(member2));//예외가 발생해야 한다.
assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
}
}