[Way to PM] 백엔드(스프링부트) - JPA Update Method

2024. 3. 20. 23:14[Way to PM] 백 엔드

Over View

해당 글은 스프링부트 프레임워크의 핵심 개념 중 기본인 JPA  수정 메서드 구현에 대해 다룹니다.


 기본적으로 JPA로 데이터 접근시 @Repository로 주입된 클래스는 JPArepository를 상속받아 Create는 save~() 메서드를 통해, Read는 find~() 메서드를 통해, Delete는 Delete~() 메서드를 통해 쿼리문을 작성하지 않고 기능을 간단히 구현할 수 있습니다. 

 하지만 Update 메서드는 부재되어 있기 때문에 레포지토리 클래스에 커스텀으로 메서드를 선언하거나, 엔티티를 update할 메서드를 서비스에 선언해 @Transcational로 관리하는 것입니다. 

import com.estsoft.blogjpa.domain.Article;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;
@Repository
public interface BlogRepository extends JpaRepository<Article, Long> {
//    List<Article> findById (String title);

//    void deleteByContent (String content);

    //JPQL = Java Persistence Query Language
    @Modifying
    @Query("update Article set title = :title where id = :id")
    void updateTitle(Long id, String title);
}

  다음과 같이 커스텀 메서드를 선언하는데, JPQL로 수행할 기능을 선언하고 @Modifying으로 수정에 대한 메서드라는 것을 선언해 오류를 방지합니다.

@Transactional
    public Article update(Long id, AddArticleRequest request) {
        Article article = findById(id);
        article.update(request.getTitle(),request.getContent());
        return article;
        //public void update(String title, String content) {
        //this.title = title;
        //this.content = content; 엔티티에 선언된 메서드
    }
    }
    @Transactional
    public Article updateTitle(Long id, AddArticleRequest request) {
        Article article = findById(id);
        blogRepository.updateTitle(id, request.getTitle());
        return article;
    }

 또는 엔티티 클래스에 update메서드를 선언하고 서비스에서 수정을 할 수 있습니다. 여기서 void로 반환해도 DB에 변경사항이 그대로 반영되는데, 이는 @Transactional을 통해 해당 메서드가 데이터베이스 관련 작업이라는 것을 선언하면 JPA 영속성 컨텍스트에서 관리되면서 void로 반환되어도 수행된 작업은 DB에 그대로 반영됩니다.

 만약 @Transactional을 적용하지 않고 해당 메서드를 실행할 컨트롤러에 요청을 보내면 DB에 변경사항이 적용되지 않습니다.