🕶 업데이트 기능을 만들어 봅시다!.
- Controller 클래스에 기능 추가해보기!
@PutMapping("/api/v1/posts/{id}") -> http put() 사용합니다.
public Long update(@PathVariable Long id, @RequestBody PostsUpdateRequestDto requestDto) {
return postsService.update(id, requestDto);
}
updateRequestDto 클래스를 활용하여 업데이트 할 데이터를 담아서 엔티티에 전달하게 합니다.
- updateRequestDto 클래스 생성해보기!
@Getter
@NoArgsConstructor
public class PostsUpdateRequestDto{
private String title;
private String content;
@Builder
public PostsUpdateRequestDto(String title, String content) {
this.title = title;
this.content = content;
}
}
- Service 클래스에 update() 기능 추가해보기!
@Transactional
public Long update(Long id, PostsUpdateRequestDto requestDto) {
Posts entity = getEntity(id);
entity.update(requestDto.getTitle(), requestDto.getContent());
return entity.getId();
}
트랜잭션 실패로 인해 데이터의 무결성과 지속성 영속성을 보장하기 위해 @Transactional 를 사용합니다.
코드를 보면 업데이트를 하는 쿼리문은 보이질 않습니다.
😭 쿼리문이 없는데 업데이트가 어떻게 되나요????
JPA 의 영속성 컨텍스트 의 특징으로 업데이트 쿼리문을 안날려도 업데이트가 됩니다. 영속성 컨텍스트 란 엔티티를 영구 저장하는 환경 이라고 합니다.
JPA 의 엔티티 매니저가 활성화 된 상태 (Spring Data JPA 를 사용하면 디폴트 값이 활성 상태입니다.) 로 트랜잭션에서 데이터베이스에서 데이터를 가져오면 이 데이터는 영속성 컨텍스트가 유지된 상태입니다.
이 상태에서 해당 데이터의 값을 변경하면 트랜잭션이 끝나는 시점에 해당 테이블에 반영이 되어 업데이트 쿼리문을 날리지 않아도 업데이트가 될 수 있는 겁니다.
- Entity 클래스에 update() 기능 추가!!
public void update(String title, String content) {
this.title = title;
this.content = content;
}
- getEntity() 살펴보기!
private Posts getEntity(Long id) {
return postsRepository.findById(id)
.orElseThrow(()-> new IllegalArgumentException("존재하는 게시글이 없습니다."));
}
findById() 기능에서도 중복된 코드를 사용하므로 메서드를 따로 추출하여 리펙토링을 하였습니다.
🕶 테스트 코드를 작성해봅시다.
- updateRequestDto 클래스 테스트
@Test
@DisplayName("PostsUpdateRequestDto_TEST")
void PostsUpdateRequestDtoTest() {
// given
String expectedTitle = "테스트";
String expectedContent = "테스트 중 입니다.";
// when
PostsUpdateRequestDto requestDto = PostsUpdateRequestDto.builder()
.title("테스트")
.content("테스트 중 입니다.")
.build();
// then
assertThat(requestDto.getTitle()).isEqualTo(expectedTitle);
assertThat(requestDto.getContent()).isEqualTo(expectedContent);
}
- Service 클래스 update 테스트
@BeforeEach
public void beforeEach() {
PostsSaveRequestDto dto = PostsSaveRequestDto.builder()
.title("테스트1")
.content("테스트 중 입니다.1")
.author("홍길동1")
.build();
postsService.save(dto);
}
@AfterEach
public void afterEach() {
postsRepository.deleteAll();
}
@Test
@DisplayName("Update_된다")
void update() {
// given
Long findId = 1L;
String expectedTitle = "테스트 수정";
String expectedContent = "테스트 중 입니다. 수정";
PostsUpdateRequestDto updateRequestDto = PostsUpdateRequestDto.builder()
.title(expectedTitle)
.content(expectedContent)
.build();
// when
postsService.update(findId, updateRequestDto);
// then
PostsResponseDto updatePosts = postsService.findById(1L);
assertThat(updatePosts.getTitle()).isEqualTo(expectedTitle);
assertThat(updatePosts.getContent()).isEqualTo(expectedContent);
}
테스트 코드가 실행 되기 전에 domain 의 데이터 값을 저장 하여 update 기능을 검증 합니다.
- Controller 클래스 테스트
@BeforeEach
public void beforeEach() {
postsRepository.save(PostsSaveRequestDto.builder()
.title("테스트1")
.content("테스트 중 입니다.1")
.author("홍길동1")
.build()
.toEntity());
}
@AfterEach
public void afterEach() {
postsRepository.deleteAll();
}
@Test
@DisplayName("Update_된다!!!!")
void update() {
// given
Posts posts = postsRepository
.findById(1L)
.orElseThrow(()-> new IllegalArgumentException("존재하지 않습니다."));
Long updatedId = posts.getId();
String expectedTitle = "테스트2";
String expectedContent = "테스트 중 입니다.2";
PostsUpdateRequestDto requestDto = PostsUpdateRequestDto.builder()
.title(expectedTitle)
.content(expectedContent)
.build();
String url = "<http://localhost>:" + port + "/api/v1/posts/" + updatedId;
HttpEntity<PostsUpdateRequestDto> postsUpdateRequestDtoHttpEntity =
new HttpEntity<>(requestDto);
// when
ResponseEntity<Long> responseEntity =
restTemplate.exchange(url, HttpMethod.PUT, postsUpdateRequestDtoHttpEntity, Long.class);
// then
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(responseEntity.getBody()).isGreaterThan(0L);
List<Posts>all = postsRepository.findAll();
assertThat(all.get(0).getTitle()).isEqualTo(expectedTitle);
assertThat(all.get(0).getContent()).isEqualTo(expectedContent);
}
테스트 코드가 실행 되기 전에 domain 의 데이터 값을 저장 하여 update 기능을 검증 합니다.
🕶 로그를 살펴보자!
업데이트 쿼리가 실행 되는 것을 살펴 볼 수 있습니다.!
'Book > Spring boot 와 AWS로 혼자 구현하는 웹서비스' 카테고리의 다른 글
[Book] 15) 머스테치로 화면 구성을 해보자! -2 (0) | 2022.04.01 |
---|---|
[Book] 14) 머스테치로 화면 구성을 해보자! -1 (0) | 2022.04.01 |
[Book] 13) JPA Auditing으로 생성시간/수정시간 자동화 하기! (0) | 2022.04.01 |
[Book] 12) H2 DB 웹 콘솔에서 직접 접근해보자! (0) | 2022.04.01 |
[Book] 10) API 만들어보기! -3 (0) | 2022.03.31 |
[Book] 9) API 만들어보기! - 2 (0) | 2022.03.30 |
[Book] 8) API 만들어보기! - 1 (0) | 2022.03.30 |
[Book] 7) 출력되는 쿼리문을 MySQL 문법으로 수정 후 이슈 (0) | 2022.03.30 |