프로젝트 시작하기

코드 굽는 제빵사·2021년 1월 7일

프로젝트 시작하기

H2 데이터베이스 설정하기

  • 실행 권한이 없으므로 chomod 755 h2.sh 명령어 실행하기.
  • jdbc:h2:~/projectname
  • ~/projectname.mv.db 파일 생성 되었는지 확인.
  • 생성 후 jdbc:h2:tcp://localhost/~/projectname 으로 접속 가능.

projectname은 자신의 프로젝트명으로 바꾸어 DB를 생성 하도록 한다.


기본적인 유저만들기

문제: User 기본 키는 무엇으로 지정해야 할까?

@GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

원래 처음에 Spring CRUD를 배울 때 이렇게 1부터 순차적으로 증가 하도록 만들었다. 하지만 실무에선 이렇게 키를 사용하지 않는다고 한다.

그렇다면 어떻게 해야 할지 고민되었다.

JPA는 세가지의 기본 키 생성 전략을 갖고 있다.

IDENTITY : 기본키 생성을 데이터 베이스에 위임한다.
주로 MySQL, PostgresSQL, SQL Server, DB2에서 사용된다. 이 생성 전략은 엔티티를 데이터베이스에 저장하고 식별자를 구할 수 있으므로 트랙재션을 지원하는 쓰기 지연이 동작하지 않는다.
SEQUENCE : 데이터베이스 시퀀스를 사용해서 기본 키를 할당한다.
데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트이다. 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용 가능하다.
TABLE : 키 생성 테이블을 사용한다.

JPA 키 생성 전략에 대해 잘 정리 해둔 블로그 참고 자료

데이터 베이스 의존적인 설정입니다. DB Sharding을 할 경우 데이터베이스 마다 각각 다시 증가하게 되어 키가 유일하지 않다고 합니다. 깃허브 기본전략을 사용하면 DB 샤딩 할때 생기는 문제를 읽었습니다.

해결: User 기본키는 UUID를 활용하자

UUID사용에 관한 자세한 컬리 기술 블로그를 참고하여 아래와 같이 ID를 증가하도록 만들었습니다.

@Id
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "uuid2")
    @Column(columnDefinition = "BINARY(16)")
    private UUID id;

기본 엔티티 생성 테스트는 어떻게 하지?

spring-boot-starter-test에서는 아래와 같은 테스트 라이브러리를 포함하고있습니다.

JUnit 5 : Java 애플리케이션 단위 테스트를위한 사실상의 표준입니다.
Spring Test & Spring Boot Test : Spring Boot 애플리케이션을위한 유틸리티 및 통합 테스트 지원.
AssertJ : 유창한 주장 라이브러리.
Hamcrest : matcher 객체의 라이브러리 (제약 조건 또는 술어라고도 함).
Mockito : 자바 모의 프레임 워크.
JSONassert : JSON 용 어설 션 라이브러리입니다.
JsonPath : JSON 용 XPath.

라이브러리를 지원 해주는 것은 알겠는데 어떻게 테스트 해야 할지 고민이었습니다. 처음 Spring을 접할 땐
@SpringBootTest @Transactional 어노테이션을 구성해서 테스트 했었지만 단위 테스트별로 구성 할 줄 알아야 한다고 들었습니다. @SpringBootTest를 거치지 않고 어떻게 해야 할지 찾아보았습니다.

DataJpaTest 어노테이션 사용법

인 메모리 임베디드 데이터베이스는 빠르고 설치가 필요하지 않기 때문에 테스트에 용이하다고 합니다.
아래와 같이 TestEntityManay와 assertj의 assertThat를 활용해서 기본 엔티티를 검증 할 수 있습니다.

@DataJpaTest
public class StoreRepositoryTest {

    @Autowired
    StoreRepository storeRepository;

    @Autowired
    StoreUserRepository storeUserRepository;

    @Autowired
    TestEntityManager tm;

    @Test
    public void createStore() throws Exception {
        //given
        Address storeAddress = new Address("seoul", "songpa-dong", "4242-42");
        Address userAddress = new Address("seoul", "gaepo-dong", "4242-42");
        StoreUser storeUser = new StoreUser("42seouler", userAddress);
        tm.persist(storeUser);
        Store store = new Store(storeUser,"store", storeAddress);
        tm.persist(store);
        //when
        Store findStore = storeRepository.findById(store.getId()).orElseThrow();
        StoreUser findStoreUser = storeUserRepository.findById(storeUser.getId()).orElseThrow();
        //then
        // 스토어의 유저 검증
        assertThat(findStore.getStoreUser()).isEqualTo(storeUser);
        // 스토어 아이디 검증
        assertThat(findStore.getId()).isEqualTo(store.getId());
        // 스토어 이름 검증
        assertThat(findStore.getName()).isEqualTo(store.getName());
        // 스토어 주소 검증
        assertThat(findStore.getAddress().getStreet()).isEqualTo(store.getAddress().getStreet());
        assertThat(findStore.getAddress().getZipcode()).isEqualTo(store.getAddress().getZipcode());
        assertThat(findStore.getAddress().getCity()).isEqualTo(store.getAddress().getCity());
    }
}

0개의 댓글