본문 바로가기

Spring boot/Blog 프로젝트 만들기(JPA)

완성 코드 STEP 02 - 게시글 삭제 ( JPA API , JPQL 쿼리 사용, 인증(세션 로직 추가 )

BoardRepository 에서 게시글 삭제 쿼리를 만들어 보자. JPA API ,
JPQL 객체 지향 쿼리 작성 (삭제 권한)
package com.tenco.blog_v1.board;

import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@RequiredArgsConstructor
@Repository // IoC
public class BoardRepository  {

    private final EntityManager em;

    /**
     * 게시글 조회 메서드
     * @param id 조회할 게시글 ID
     * @return 조회된 Board 엔티티, 존재하지 않으면 null 반환
     */
    public Board findById(int id) {
         return em.find(Board.class, id);
    }

    /**
     * JPQL의 FETCH 조인 사용 - 성능 최적화
     * 한방에 쿼리를 사용해서 즉, 직접 조인해서 데이터를 가져 옵니다.
     * @param id
     * @return
     */
    public Board findByIdJoinUser(int id) {
        // JPQL -> Fetch join 을 사용해 보자.
        String jpql = " SELECT b FROM Board b JOIN FETCH b.user WHERE b.id = :id ";
        return em.createQuery(jpql, Board.class)
                .setParameter("id", id)
                .getSingleResult();
    }

    /**
     * 모든 게시글 조회
     * @return 게시글 리스트
     */
    public List<Board> findAll() {
        TypedQuery<Board> jpql = em.createQuery(" SELECT b FROM Board b ORDER BY b.id DESC ", Board.class);
        return jpql.getResultList();
    }

    // em.persist(board) -> 비영속 상태인 엔티티를 영속상태로 전환
    @Transactional
    public Board save(Board board) {
        em.persist(board);
        return board;
    }

    /**
     * 게시글 삭제하기
     * @param id
     */
    // DELETE JPA API 메서드를 활용(영속성 컨텍트), JPQL --> QDSL .. namedQuery. ...
    @Transactional // 트랜잭션 내에서 실행되도록 보장
    public void deleteById(int id) {
        Query jpql =  em.createQuery("DELETE FROM Board b WHERE b.id = :id");
        jpql.setParameter("id", id);
        jpql.executeUpdate();
    }

    /**
     *
     *  JPA API 만들어 보세요
     */
    // DELETE JPA API 메서드를 활용(영속성 컨텍트), JPQL --> QDSL .. namedQuery. ...
    @Transactional // 트랜잭션 내에서 실행되도록 보장
    public void deleteByIdJPA(int id) {
        
    }

}

 

 

 

 

BoardController 에서 게시글 삭제 요청을 만들어 보자
  // 주소설계 - http://localhost:8080/board/10/delete ( form 활용이기 때문에 delete 선언)
  // form 태크에서는 GET, POST 방식만 지원하기 때문이다.
  @PostMapping("/board/{id}/delete")
  public String delete(@PathVariable(name = "id") Integer id) {
      // 유효성, 인증검사
      // 세션에서 로그인 사용자 정보 가져오기 -> 인증(로그인 여부) , 인가(권한 - 내글?)
      User sessionUser = (User) session.getAttribute("sessionUser");

      if (sessionUser == null) {
          return "redirect:/login-form";
      }

      // 권한 체크
      Board board = boardRepository.findById(id);
      if(board == null) {
          return "redirect:/error-404";
      }
      if( ! board.getUser().getId().equals(sessionUser.getId())) {
          return "redirect:/error-403"; // 추후 수정
      }

      // 게시글 삭제
      boardRepository.deleteById(id);
      // boardNativeRepository.deleteById(id);
      return "redirect:/";

  }

 

 

728x90