프로젝트 시작하기
H2 데이터베이스 설정하기
projectname은 자신의 프로젝트명으로 바꾸어 DB를 생성 하도록 한다.
기본적인 유저만들기
@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 샤딩 할때 생기는 문제를 읽었습니다.
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를 거치지 않고 어떻게 해야 할지 찾아보았습니다.
인 메모리 임베디드 데이터베이스는 빠르고 설치가 필요하지 않기 때문에 테스트에 용이하다고 합니다.
아래와 같이 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());
}
}