์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ

STEP 02 - ๊ฒŒ์‹œ๊ธ€ ์“ฐ๊ธฐ

๋ฏธ๋กœ910 2024. 10. 8. 12:45
๐Ÿ’ก
JPA๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ํ•™์Šตํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ๋Š”๋ฐ์ดํ„ฐ ์ €์žฅ, DTO ์‚ฌ์šฉ, ์ปจํŠธ๋กค๋Ÿฌ ๊ตฌํ˜„ ๋“ฑ์„ ๋‹ค๋ฃจ๋ฉฐ, ORM์˜ ์˜์†์„ฑ ๊ด€๋ฆฌ์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ์‹ฌํ™”ํ•ฉ๋‹ˆ๋‹ค.

 

BoardRepository save ๋ฉ”์„œ๋“œ ๊ตฌํ˜„ํ•˜๊ธฐ

๋ชฉํ‘œ: Board ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๋Š” save ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

 

BoardRepository ์ฝ”๋“œ ์ถ”๊ฐ€ (save)
@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;
    }

 

BoardDTO
package com.tenco.blog_v1.board;

import com.tenco.blog_v1.user.User;
import lombok.Data;

public class BoardDTO {

    @Data
    public static class SaveDTO {
        private String title;
        private String content;

        public Board toEntity(User user) {
            return Board.builder()
                    .title(title)
                    .content(content)
                    .user(user)
                    .build();
        }

    }

}

 

BoardController ์ฝ”๋“œ ์ˆ˜์ • (save)
package com.tenco.blog_v1.board;

import com.tenco.blog_v1.user.User;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Slf4j
@RequiredArgsConstructor
@Controller
public class BoardController {

    // ๋„ค์ดํ‹ฐ๋ธŒ ์ฟผ๋ฆฌ ์—ฐ์Šต
    private final BoardNativeRepository boardNativeRepository;
    // JPA API, JPQL
    private  final BoardRepository boardRepository;
    private  final HttpSession session;

    // ์ฃผ์†Œ ์„ค๊ณ„: http://localhost:8080/board/1
    // ํŠน์ • ๊ฒŒ์‹œ๊ธ€ ์š”์ฒญ ํ™”๋ฉด
    @GetMapping("/board/{id}")
    public String detail(@PathVariable (name = "id" ) Integer id, HttpServletRequest request){
       // JPA API ์‚ฌ์šฉ
        // Board board = boardNativeRepository.findById(id);

        // JPQL FETCH join ์‚ฌ์šฉ
        Board board = boardRepository.findByIdJoinUser(id);
        request.setAttribute("board", board);
        return "board/detail";
    }


    @GetMapping("/")
    public String index(Model model){

        List<Board> boardList = boardRepository.findAll();
        model.addAttribute("boardList", boardList);
        return "index";
    }

    // ์ฃผ์†Œ ์„ค๊ณ„: http://localhost:8080/board/save-form
    // ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ ํ™”๋ฉด
    @GetMapping("/board/save-form")
    public String saveForm(){
        return  "board/save-form";
    }

    // ๊ฒŒ์‹œ๊ธ€ ์ €์žฅ
    // ์ฃผ์†Œ ์„ค๊ณ„: http://localhost:8080/board/save
    @PostMapping("/board/save")
    public  String save(@ModelAttribute BoardDTO.SaveDTO reqDto){
        User sessionUser = (User) session.getAttribute("sessionUser");

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

        // ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „๋‹ฌ ๋˜์—ˆ๋Š”์ง€ ํ™•์ธ
        log.warn("save ์‹คํ–‰: ์ œ๋ชฉ-{}, ๋‚ด์šฉ={}", reqDto.getTitle(), reqDto.getContent());

        // boardNativeRepository.save(title, content);
        // SaveDTO์—์„œ toEntity ์‚ฌ์šฉํ•ด์„œ Board ์—”ํ‹ฐํ‹ฐ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ์ธ์ˆ˜ ๊ฐ’์œผ๋กœ User ์ •๋ณด๋ฅผ ๋„ฃ์—ˆ๋‹ค.
        // ๊ฒฐ๊ตญ Board ์—”ํ‹ฐํ‹ฐ๋กœ ๋ฐ˜ํ™˜์ด ๋œ๋‹ค.
        boardRepository.save(reqDto.toEntity(sessionUser));
        return  "redirect:/";
    }

    
    // ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • ํ™”๋ฉด ์š”์ฒญ
    // ์ฃผ์†Œ ์„ค๊ณ„: http://localhost:8080/board/id/update
    @GetMapping("/board/{id}/update-form")
    public String updateForm(@PathVariable(name = "id") Integer id, HttpServletRequest request){
        Board board = boardNativeRepository.findById(id);
        request.setAttribute("board", board);
        return  "board/update-form";    // src/main/resources/templates/board/update-form.mustache
    }

    // ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • ์š”์ฒญ ๊ธฐ๋Šฅ
    // ์ฃผ์†Œ ์„ค๊ณ„: http://localhost:8080/board/{id}/update
    @PostMapping("/board/{id}/update")
    public String update(@RequestParam(name = "id") Integer id, @RequestParam(name = "title") String title, @RequestParam(name = "content") String content){

        boardNativeRepository.updateById(id, title, content);
        //
        return "redirect:/board/" + id;
    }




}

 

@ModelAttribute ์™€ @RequestBody ์— ๋Œ€ํ•œ ์ฐจ์ด์ ์„ ์ดํ•ดํ•˜์ž