본문 바로가기
스프링

스프링 부트 JPA 게시물 수정 / 변경

by DarrenH 2022. 1. 17.
반응형

저번 게시물에서는 게시물 작성에 대해서 포스팅했는데요 이번에는 게시물 수정에 대하여 작성해보려고 합니다.

게시물 작성과 큰 차이는 없습니다. 소스코드먼저 보겠습니다.

저번 게시물과 동일하게 PostsResponseDto 클래스가 있고, PostApiController 클래스가 있습니다. 저희가 게시물 작성 시에는 PostsSaveRequestDto를 작성했는데요 이번에는 수정을 하기 위해 PostsUpdateRequestDto클래스를 작성하도록 하겠습니다.

package com.jojoldu.book.web.dto; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @NoArgsConstructor @Getter public class PostsUpdateRequestDto { private String title; private String content; @Builder public PostsUpdateRequestDto(String title, String content) { this.title = title; this.content = content; } }

보시면 PostsSaveRequestDto클래스와 조금 다른 점이있습니다. author변수가 사라져 있는데요 수정 시에는 author은 수정 안 하기 때문에 빼주게 되었고요, 마찬가지로 @Builder를 작성해줍니다.

그다음은 PostsService클래스를 보겠습니다.

@RequiredArgsConstructor @Service public class PostsService { private final PostsRepository postsRepository; @Transactional public Long save(PostsSaveRequestDto requestDto) { return postsRepository.save(requestDto.toEntity()).getId(); } @Transactional public Long update(Long id, PostsUpdateRequestDto requestDto) { Posts posts = postsRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("해당 사용자가 없습니다. id="+ id)); posts.update(requestDto.getTitle(), requestDto.getContent()); return id; } public PostsResponseDto findById(Long id) { Posts entity = postsRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("해당 사용자가 없습니다. id="+id)); return new PostsResponseDto(entity); } }

보시면 JDBC 트랜잭션 update와 findById메소드를 작성해줍니다. DB와 직접적으로 접근하는 Repository클래스에 접근한 다음에 해당 id가 있는지 검사를 합니다. 검사 후 IllegalArgumentException이 발생하면 다음과 같은 문구를 출력시켜줍니다. 정상적으로 실행될 경우 post 클래스에 update메서드를 호출해줍니다.

Post 클래스 소스코드

@Getter @NoArgsConstructor @Entity //Table과 link될 클래스임을 명시 Setter 생성 금지 다른 이름으로 정확히 명시해서 set은 가능 public class Posts { @Id //PK 명시 @GeneratedValue(strategy = GenerationType.IDENTITY) //auto_increment 명시) private Long id; @Column(length = 500, nullable = false) private String title; @Column(columnDefinition = "TEXT", nullable = false) private String content; private String author; @Builder public Posts(String title, String content, String author) { this.title = title; this.content = content; this.author = author; } public void update(String title, String content) { this.title = title; this.content = content; } }

그 후 해당 아이디를 반환해줍니다.


그리고 이번에는 PostApiController 클래스를 보도록 하겠습니다.

@RequiredArgsConstructor @RestController public class PostApiController { private final PostsService postsService; @PostMapping("/api/v1/posts") public Long save(@RequestBody PostsSaveRequestDto requestDto) { return postsService.save(requestDto); } @PostMapping("/api/v1/posts/{id}") public Long update(@PathVariable Long id, @RequestBody PostsUpdateRequestDto requestDto) { return postsService.update(id, requestDto); } @GetMapping("/api/v1/posts/{id}") public PostsResponseDto findById(@PathVariable Long id) { return postsService.findById(id); } }

이전 글에서는 save메소드만 존재했는데 지금 보시면 update와 findById메서드가 추가되었습니다. 코드의 경우 아까 만들어 놓은 Service 클래스의 update메서드를 호출해줍니다. 해당 경로(/api/v1/posts/{id}) 로 이동하게 되면 해당 메서드를 실행하게 됩니다.

클래스의 순서를 설명 드리자면
1. PostApiController 클래스에서 해당 경로에 맞는 메서드 호출
2. postsService 클래스에서 호출된 메소드 실행
3. update()의 경우 posts.update()를 실행

지금까지 코드를 보시면 단순한데 의문이 드실겁니다. 게시물 작성이랑 다르게 Repository클래스를 전혀 이용안 해서 실질적으로 쿼리를 날리는 부분이 없습니다. 이는 JPA의 영속성 컨텍스트 때문인데요. 엔티티를 영구 저장하는 환경이라는 뜻입니다. 이는 트랜잭션 안에서 데이터베이스에서 데이터를 가져오면 영속성이 유지가 되는 상태인데요. 이 상태에서 데이터의 값을 변경하면 트랜잭션이 끝나는 시점에서 해당 테이블에 변경분을 반영하게 됩니다. 결국은 Posts클래스의 값을 변경해놓으면 트랜잭션이 끝나는 시점에 자동으로 update가 진행이 됩니다. 이러한 개념을 더티 체킹이라고 합니다.

그럼 포스팅 마치겠습니다.

반응형