ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [게시판 만들기 (5)] 게시글 조회
    Spring Boot 2024. 1. 14. 02:23

     

     

    BoardController에 findById 메서드를 추가한다.

    특정 ID에 해당하는 게시글을 조회하고, 해당 게시글의 조회수를 증가시킨 후에

    상세페이지(detail.html)로 이동하는 메서드이다.

     

    [ BoardController ]

    @GetMapping("/{id}")
    public String findById(@PathVariable Long id, Model model){
        /*
            해당 게시글의 조회수를 하나 올리고
            게시글 데이터를 가져와서 detail.html에 출력
         */
        boardService.updateHits(id);
        BoardDTO boardDTO = boardService.findById(id);
        model.addAttribute("board", boardDTO);
        return "detail";
    }

     

    public String findById(@PathVariable Long id, Model model){

    @PathVariable 어노테이션을 사용하여 URL 경로에서 추출한 'id' 값을 메서드의 매개변수로 받는다.

    Model 객체는 뷰에 데이터를 전달하기 위한 스프링의 클래스이다.

     

    boardService.updateHits(id);

    boardService를 통해 updateHits 메서드를 호출하여 해당 id에 해당하는 게시글의 조회수를 증가시킨다.

     

    BoardDTO boardDTO = boardService.findById(id);

    boardService를 통해 findById 메서드를 호출하여 해당 id에 해당하는 게시글의 정보를 가져온다.

     

    model.addAttribute("board", boardDTO);

    Model 객체에 board라는 속성명으로 boardDTO를 추가한다.

    이를 통해 해당 데이터를 뷰로 전달할 수 있다.

     

    return "detail";

    최종적으로 detail이라는 뷰 이름을 반환한다. 

     

     

     

     

     

     

     

     

     

     

     

    BoardService 클래스에 updateHits 메서드와 findById 메서드를 추가한다.

     

    [ BoardService ]

    @Transactional
    public void updateHits(Long id) {
        boardRepository.updateHits(id);
    }
    
    public BoardDTO findById(Long id) {
        Optional<BoardEntity> optionalBoardEntity = boardRepository.findById(id);
        if (optionalBoardEntity.isPresent()) {
            BoardEntity boardEntity = optionalBoardEntity.get();
            BoardDTO boardDTO = BoardDTO.toBoardDTO(boardEntity);
            return boardDTO;
        } else {
            return null;
        }
    }

     

    <updateHits 메서드>

     

    @Transactional

    이 어노테이션은 해당 메서드가 트랜잭션 내에서 실행되어야 함을 나타낸다

     

    public void updateHits(Long id) {

    해당 ID에 해당하는 게시글의 조회수를 업데이트 하는 메서드이다.

     boardRepository.updateHits(id); 를 호출하여 게시글 조회수를 업데이트한다.

    이는 커스텀 쿼리를 사용하여 해당 ID에 해당하는 게시글의 조회수를 증가시키는 쿼리를 실행한다.

     

     

    <findById 메서드>

     

    public BoardDTO findById(Long id) {

    해당 ID에 해당하는 게시글을 가져오는 메서드이다.

    boardRepository.findById(id); 를 호출하여 Optional<BoardEntity> 객체를 얻는다.

    이 객체는 게시글이 존재할 수도, 존재하지 않을 수도 있다.

    if (optionalBoardEntity.isPresent()) { 를 사용하여 게시글이 존재하는지 확인하고,

    존재한다면  BoardEntity boardEntity = optionalBoardEntity.get(); 로 BoardEntity 객체를 가져와            

    BoardDTO.toBoardDTO(boardEntity); 를 통해

    return boardDTO; 인 BoardDTO로 변환하여 반환한다.

    게시글이 존재하지 않으면 null을 반환한다. 

     

     

     

     

     

     

     

     

     

     

     

     

    BoardRepository 인터페이스에 커스텀 쿼리를 정의한다.

     

    [ BoardRepository ]

    public interface BoardRepository extends JpaRepository<BoardEntity, Long> {
        // update board_table set board_hits=board_hits+1 where id=?
        @Modifying
        @Query(value = "update BoardEntity b set b.boardHits=b.boardHits+1 where b.id=:id")
        void updateHits(@Param("id") Long id);
    }

     

    @Modifying

    이 어노테이션은 JPQL(QueryDSL를 통해 작성된 쿼리)을 사용하여 데이터를 수정하는 메서드임을 나타낸다.

    JPQL은 객체지향 쿼리 언어로, 엔티티 객체를 기반으로 쿼리를 작성할 수 있다.

     

    @Query(value = "update BoardEntity b set b.boardHits=b.boardHits+1 where b.id=:id")

    JPQL 쿼리를 정의한다. 

    이 쿼리는 BoardEntity 의 조회수 (boardHits)를 1증가시키는 업데이트 쿼리이다.

    :id는 쿼리에 사용되는 매개변수로, 실제 실행 시에 파라미터로 전달된다.

     

    void updateHits(@Param("id") Long id);

    쿼리 메서드로, 조회수를 업데이트 하는 역할을 한다.

    @Param("id") 어노테이션은 메서드 파라미터와 JPQL 쿼리의 매개변수를 연결한다.

    이 경우, 메서드 파라미터 id가 JPQL 쿼리의 :id 매개변수에 바인딩된다.

     

     

     

     

     

     

     

     

     

     

     

     

    templates 패키지에 detail.html 파일을 추가한다.

     

    [ detail.html ]

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>detail</title>
        <!-- jquery cdn -->
        <script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
    </head>
    <body>
    <table>
        <tr>
            <th>id</th>
            <td th:text="${board.id}"></td>
        </tr>
        <tr>
            <th>title</th>
            <td th:text="${board.boardTitle}"></td>
        </tr>
        <tr>
            <th>writer</th>
            <td th:text="${board.boardWriter}"></td>
        </tr>
        <tr>
            <th>date</th>
            <td th:text="${board.boardCreatedTime}"></td>
        </tr>
        <tr>
            <th>hits</th>
            <td th:text="${board.boardHits}"></td>
        </tr>
        <tr>
            <th>contents</th>
            <td th:text="${board.boardContents}"></td>
        </tr>
        <tr th:if="${board.fileAttached == 1}">
            <th>image</th>
            <td><img th:src="@{|/upload/${board.storedFileName}|}" alt=""></td>
        </tr>
    </table>
    <button onclick="listReq()">목록</button>
    <button onclick="updateReq()">수정</button>
    <button onclick="deleteReq()">삭제</button>
    
    </body>
    <script th:inline="javascript">
        const listReq = () => {
            console.log("목록 요청");
            const page = [[${page}]];
            location.href = "/board/paging?page="+page;
        }
        const updateReq = () => {
            console.log("수정 요청");
            const id = [[${board.id}]];
            location.href = "/board/update/" + id;
        }
        const deleteReq = () => {
            console.log("삭제 요청");
            const id = [[${board.id}]];
            location.href = "/board/delete/" + id;
        }
    </script>
    </html>

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    실행시켜보쟈.

    http://localhost:8092/board/1 의 detail 화면이다.

    조회수는 새로고침하는대로 늘어난다.

Designed by Tistory.