(Spring) Spring DB 접근 기술

(Spring) Spring DB 접근 기술

1. H2 데이터베이스 설치

– 교육에 좋은

– 다운로드(1.4.200) -> 모든 플랫폼)

– cd h2 -> cd bin -> chmod 755 h2.sh(권한) -> ./h2.sh(실행)

– 실행되고 IP가 캡처되지 않은 경우 (IP:8082 -> localhost:8082)

– JDBC URL -> jdbc:h2~/test -> 연결

– ll -> ls -all -> test.mv.db 파일이 존재해야 함

– 파일에 직접 접근하지 말고 여러 곳에서 접근 -> JDBC URL -> jdbc:h2:tcp://localhost/~/test

– 테이블 생성

– DDL 관리 -> src 외부에 sql 폴더를 생성하여 ddl.sql(command) 생성 및 관리 ex) drop table, create table~

2. 순수한 Jdbc

– 우선 사항

-JdbcMemberRepository

public class JdbcMemberRepository implements MemberRepository {
  @Override
  public Member save(Member member) {
    return null;
  }
  
  @Override
  public Optional<Member> findById(Long id) {
    return Optional.empty();
  }
}

* 지침

-> DataSourceUtils를 통한 getConnection 및 releaseConnection(연결, 해제)

-> 이렇게 하면 데이터베이스 트랜잭션이 활성 상태로 유지됩니다.

SpringConfig

-> @Bean 저장소는 부분적으로 수정된 반환 -> MemoryMemberRepo -> JdbcMemberRepo(dataSource)

데이터 소스

private DataSource dataSource;

@Autowired
public SpringConfig(DataSource dataSource) {
  this.dataSource = dataSource;
}

-> Spring 자체를 사용하여 데이터 소스 생성 및 주입


컨트롤러는 서비스에 따라 달라지고 서비스는 Repo에 따라 달라집니다.

-> Jdbc로 쉽게 변경 가능

** 개방 폐쇄 원칙(OCP)

= 확장에는 개방, 수정/변경에는 폐쇄.

= 연산 코드(기존 코드)는 기능을 변경해도 수정 불가

= 스프링 DI

3. 스프링 통합 테스트

@SpringBootTest 주석 + @Transactional 주석

@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("이미 존재하는 회원입니다.

"); } }

@SpringBootTest : Spring 컨테이너와 테스트를 함께 실행.

@트랜잭션 : 테스트 사례에 이 주석이 있는 경우, 테스트가 시작되기 전에 거래를 시작하십시오., 테스트 완료 후 항상 롤백.

이 방법 DB데이터가 남아 있지 않아 다음 테스트에 영향을 미치지 않습니다.

.

-> aftereach, beforeeach가 필요 없습니다!

* 더 나은 순수 단위 테스트(통합 테스트보다)

* 스프링 컨테이너 없이 테스트하는 것이 가장 좋습니다.

4. 스프링 JdbcTemplate(Mybatis와 유사)

– 라이브러리(실무에서 자주 사용!
)

– JDBC API에서 대부분의 중복 코드 제거

– SQL은 손으로 작성해야 합니다.

– 스프링 Jdbc 템플릿

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;
  }
  
  @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 List<Member> findAll() {
    return jdbcTemplate.query("select * from member", memberRowMapper());
  }
  
  @Override
  public Optional<Member> findByName(String name) {
    List<Member> result = jdbcTemplate.query("select * from member where name = ?", memberRowMapper(), name);
    return result.stream().findAny();
  }
    
  private RowMapper<Member> memberRowMapper() {
    return (rs, rowNum) -> {
      Member member = new Member();
      member.setId(rs.getLong("id"));
      member.setName(rs.getString("name"));
      return member;
    }; 
  }
}

* 생성자가 1개인 경우 @Autowired 생략 가능

4. 공동 행동 계획

– 기존 반복 코드 + 기본 sql 직접 ​​생성 및 실행

– SQL 및 데이터 중심 설계에서 객체 중심 설계로 패러다임 전환 가능

– 개발 효율성 향상