๐Ÿ‘จโ€๐Ÿฆฒ ๊ฒŒ์‹œํŒ CRUD๋ฅผ ๋ฉ”๋ชจ๋ฆฌ๋กœ ๊ตฌํ˜„ํ•ด ๋ณด์ž

์ด์„ฑ์›ยท2024๋…„ 2์›” 14์ผ
0

์Šคํ”„๋ง MVC

๋ชฉ๋ก ๋ณด๊ธฐ
2/2

๋ฐฑ์—”๋“œ ๊ฐ•์˜๋ฅผ ๋“ฃ๊ณ  ์ง์ ‘ ๊ฒŒ์‹œํŒCRUD๋Š” ๊ตฌํ˜„์„ ํ•ด ๋ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐ์ด ๋“ค์—ˆ๊ณ , ๊น€์˜ํ•œ๋‹˜์˜ Spring ๊ธฐ์ดˆ ๊ฐ•์˜์™€ Spring Mvc 1 ํŽธ์„ ๋“ฃ๊ณ  ์ง์ ‘ ํ•œ๋ฒˆ ๊ตฌํ˜„ํ•ด ๋ณด์ž ๋ผ๋Š” ์ž์‹ ๊ฐ์„ ์–ป์—ˆ๋‹ค!!

๋„๋ฉ”์ธ

๐Ÿงช ๊ฒŒ์‹œํŒ

  • ๊ฒŒ์‹œํŒ์—๋Š” ์•„์ด๋””, ์ œ๋ชฉ, ๋‚ด์šฉ, ํ˜„์žฌ ๋‚ ์งœ๋“ฑ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋„๋ฉ”์ธ์„ ์ƒ์„ฑํ•˜์˜€๋‹ค.
  • ์ถ”ํ›„ ์กฐํšŒ์ˆ˜๋„ ๊ตฌํ˜„์„ ๋ชฉํ‘œ๋กœ ํ•˜๊ณ  ์žˆ๋‹ค.

๊ฒŒ์‹œํŒ ๋„๋ฉ”์ธ


package board.boardservice.domain;

import lombok.Getter;
import lombok.Setter;

import java.util.Date;

@Getter
@Setter
public class Board {

    private Long id;
    private String sub;
    private String content;
    private Date date;
    private int count;

    public Board(String sub, String content, Date date) {
        this.sub = sub;
        this.content = content;
        this.date = date;
    }

    public void view(){
        count++;
    }


}

๋ ˆํฌ์ง€ํ† ๋ฆฌ

  • ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋Š” ์ถ”ํ›„ JPA๋ฅผ ๋ฐฐ์šฐ๋ฉด JPA๋ฅผ ์ ์šฉํ•˜๊ธฐ์œ„ํ•ด ๋จผ์ € ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์ถ”์ƒํ™” ์ž‘์—…์„ ์ง„ํ–‰ํ•˜์˜€๋‹ค.

BoardRepogitory


package board.boardservice.repository;

import board.boardservice.domain.Board;

import java.util.List;


public interface BoardRepository {

    Board save(Board board);
    Board findById(Long id);

    List<Board> findByAll();

    void upDate(Long id, Board board);

    void deleteBoard(Long id);

    void clearStore();



}
  • ๊ฒŒ์‹œํŒ์˜ ๊ฐ„๋‹จํ•œ ๊ธฐ๋Šฅ์œผ๋กœ๋Š” ์ฒซ๋ฒˆ์งธ ๊ฒŒ์‹œ๊ธ€์„ ์ €์žฅํ•˜๋Š” ๊ธฐ๋Šฅ
  • ํ•ด๋‹น ๊ฒŒ์‹œ๋ฌผ์„ id๋กœ ์ฐพ๋Š” ๊ธฐ๋Šฅ
  • ์ „์ฒด์˜ ๊ฒŒ์‹œ๋ฌผ์„ ์ฐพ๋Š” ๊ธฐ๋Šฅ
  • ๊ฒŒ์‹œ๊ธ€ ์—…๋ฐ์ดํŠธ ๊ธฐ๋Šฅ
  • ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ๊ธฐ๋Šฅ

MemoryRepositoty

package board.boardservice.repository;

import board.boardservice.domain.Board;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.util.*;

@Slf4j
@Repository
public class MemoryBoardRepository implements BoardRepository{

    private static final Map<Long, Board> store = new HashMap<>();
    private static long sequence = 0L;

    @Override
    public Board save(Board board) {
        board.setId(sequence++);
        store.put(board.getId(), board);
        board.view();
        return board;
    }

    @Override
    public Board findById(Long id) {
        return store.get(id);
    }



    @Override
    public List<Board> findByAll() {
        return new ArrayList<>(store.values());
    }

    @Override
    public void upDate(Long id, Board board) {
        Board findBoard = findById(id);
        findBoard.setDate(new Date());
        findBoard.setSub(board.getSub());
        findBoard.setContent(board.getContent());
    }

    @Override
    public void deleteBoard(Long id) {
        if(store.containsKey(id)){
            store.remove(id);
            log.info("์‚ญ์ œ ์™„๋ฃŒ");
        }
        else{
            log.info("ํ•ด๋‹น ์•„์ด๋””๋Š” ์—†์Šต๋‹ˆ๋‹ค");
        }
    }

    @Override
    public void clearStore(){
        store.clear();
    }
}
  • BoardRepository๋ฅผ implements ๋ฐ›์•„ ์ €์žฅ์†Œ๋ฅผ Map<Long, Board>๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜์˜€๋‹ค.
  • save() :ํ•ด๋‹น ๊ฒŒ์‹œ๋ฌผ์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ
  • findByAll(): ์ „์ฒด์˜ ๊ฒŒ์‹œ๊ธ€ ๋ฐ˜ํ™˜
  • upDate(): ํ•ด๋‹น ์•„์ด๋””๋กœ ์ €์žฅ๋˜์–ด์žˆ๋Š” ๊ฒŒ์‹œ๊ธ€์„ ์ฐพ์•„์„œ ํŒŒ๋ผ๋ฏธํ„ฐ์— ์žˆ๋Š” ๊ฒŒ์‹œ๊ธ€๋กœ ์—…๋ฐ์ดํŠธ
  • deleteBoard(): ํ•ด๋‹น ์•„์ด๋””๋กœ ์ฐพ์•„ ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ.
  • @Repository: MemoryBoardRepositoty๋ฅผ ์Šคํ”„๋ง ๋นˆ์— ๋“ฑ๋ก

์ „์ฒด์  ํ™”๋ฉด

๐Ÿ€Controller

@Controller
@RequestMapping("/basic/boards")
@RequiredArgsConstructor
public class BoardController {

    private final BoardRepository boardRepository;
  • @Controller : ์Šคํ”„๋ง ๋นˆ์— ์ปจํŠธ๋กค๋Ÿฌ ๋“ฑ๋ก
  • @RequestMapping: Default Url์„ ๋“ฑ๋ก์‹œ์ผœ ์ค€๋‹ค
  • @RequiredArgsConstructor: final์ด ๋ถ™์€ ๋ฉค๋ฒ„๋ณ€์ˆ˜๋งŒ ์‚ฌ์šฉํ•ด์„œ ์‚ฌ์šฉ์ž๋ฅผ ๋งŒ๋“ค์–ด์คŒ
  • @Autowired: ์˜์กด๊ด€๊ณ„ ์ž๋™์ฃผ์ž…(์ƒ๋žต๊ฐ€๋Šฅ)
 @GetMapping
    public String boards(Model model) {
        List<Board> boardList = boardRepository.findByAll();

        model.addAttribute("board", boardList);

        return "basic/boards";

    }
    
     @PostConstruct
    public void init() {
        boardRepository.save(new Board("ใ…‹ใ…‹", "ใ…‹ใ…‹", new Date()));
        boardRepository.save(new Board("ใ…‹ใ…‹", "ใ…‡ใ…‡", new Date()));

    }
  • url: /basic/boards์ด ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด boards() ๋ฉ”์„œ๋“œ ์ˆ˜ํ–‰ ํ›„ ์ŠคํŠธ๋ง path ๋ฐ˜ํ™˜
  • ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ Thymeleaf๋กœ ๋ Œ๋”๋ง ์ž‘์—…
  • @PostConstruct: ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ์„  ๋ฐ์ดํ„ฐ ์‚ฝ์ž…

Thymeleaf

 <tr th:each="board : ${board}">
                    <td th:text="${board.id}">user123</td>
                    <td><a th:href="@{/basic/boards/{boardId} (boardId=${board.id})}" th:text="${board.sub} ">๊ฒŒ์‹œ๊ธ€ ์ œ๋ชฉ</a></td>
                    <td th:text="${board.count}">100</td>
                    <td th:text="${board.date}">2024.02.06</td>
                </tr>

์ „์ฒด ํ™”๋ฉด

  • ํ•ด๋‹น ํŽ˜์ด์ง€๋Š” ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก๊ณผ ์ œ๋ชฉ์„ ๋ˆŒ๋ฅด๋ฉด ์ƒ์„ธ ์ œ๋ชฉ๊ณผ ๋‚ด์šฉ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค
  • ๋“ฑ๋ก์ผ์€ ๋ฉ”๋ชจ๋ฆฌ์— ๊ฒŒ์‹œ๊ธ€์ด ๋“ฑ๋ก ๋œ ์‹œ๊ฐ„์„ ๋‚˜ํƒ€๋‚ธ๋‹ค.

์ƒ์„ธ ๋ณด๊ธฐ

@GetMapping("/{boardId}")
    public String board(@PathVariable Long boardId, Model model) {
        Board board = boardRepository.findById(boardId);
        model.addAttribute("board", board);

        return "basic/board";
    }
  • ํ•ด๋‹น ์ œ๋ชฉ์„ ๋ˆŒ๋ฅด๋ฉด ๋‚ด์šฉ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
  • ํ•ด๋‹น ์•„์ด๋””๋กœ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋œ ๊ฒŒ์‹œ๊ธ€์„ ์ฐพ๊ณ  Model์— ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์€ ํ›„ ๋ Œ๋”๋ง ์ž‘์—…

  • ๋ฆฌ์ŠคํŠธ๋ฅผ ํด๋ฆญ ์‹œ ๋‹ค์‹œ ์ „์ฒด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์ „ ํ™”๋ฉด์œผ๋กœ ๋Œ์•„๊ฐ
  • ํ•ด๋‹น ๊ธ€ ์ƒํ’ˆ ์ˆ˜์ •, ์‚ญ์ œ ๊ธฐ๋Šฅ

์ƒํ’ˆ ๋“ฑ๋ก

 @GetMapping("/create")
    public String createBoardForm() {
        return "basic/addForm";
    }

    @PostMapping("/create")
    public String createBoard(@ModelAttribute Board board) {
        boardRepository.save(board);
        board.setDate(new Date());


        return "redirect:/basic/boards/" + board.getId();

    }
  • ๊ฐ™์€ Url ์ด์ง€๋งŒ Post, Get ๋‘˜๋‹ค ๋‹ค๋ฅธ ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉ
  • @GetMapping: ์€ ์ƒํ’ˆ์„ ๋“ฑ๋กํ•˜๋Š” ํผ์„ ๋ณด์—ฌ์ค€๋‹ค.
  • Post-Html Form ๋ฐฉ์‹์œผ๋กœ ์š”์ฒญ์ด ์˜ค๋ฉด @PostMapping ๋งคํ•‘ ํ›„ @ModelAttribute๋กœ Board ๊ฐ์ฒด ์ƒ์„ฑ ํ›„ Model์— ๋‹ด๋Š”๋‹ค.
  • PRG: Post / Redirect / Get ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด ํ•ด๋‹น ๋‚ด์šฉ์„ ์ƒˆ๋กœ ๊ณ ์นจ ์‹œ Post ์š”์ฒญ์ด ๊ณ„์† ๋˜๋Š”๊ฒƒ์„ ๋ง‰์Œ


  • ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก ํ›„ ๋ฆฌ์ŠคํŠธ ํ™•์ธ์„ ํ•˜๋ฉด ๊ฒŒ์‹œ๊ธ€์ด ๋“ฑ๋ก๋œ ๊ฑธ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • / ์‚ญ์ œ

 @GetMapping("/edit/{boardId}")
    public String editForm(@PathVariable Long boardId, Model model){
        Board findBoard = boardRepository.findById(boardId);

        model.addAttribute("board", findBoard);

        return "basic/edit";
    }

    @PostMapping("/edit/{boardId}")
    public String edit(@PathVariable Long boardId, @ModelAttribute Board board){
        boardRepository.upDate(boardId, board);

        return "redirect:/basic/boards/{boardId}";
    }

    @GetMapping("/delete/{boardId}")
    public String delete(@PathVariable Long boardId){
        boardRepository.deleteBoard(boardId);

        return "redirect:/basic/boards";
    }
  • ์„ธ๋ถ€ ๋ฆฌ์ŠคํŠธ์—์„œ ์ˆ˜์ •ํ•˜๊ธฐ๋ฅผ ๋ˆ„๋ฅด๋ฉด ํ•ด๋‹น ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ํผ
  • ํ•ด๋‹น ์•„์ด๋””์™€ @PostMapping์œผ๋กœ ์˜จ ๋ฐ์ดํ„ฐ๋ฅผ Create์™€ ๋™์ผํ•˜๊ฒŒ @ModelAttribute๋กœ ์ง„ํ–‰
  • ์ด ๋ฐฉ์‹ PRG ๋ฐฉ์‹ ์ง„ํ•ด
  • ์‚ญ์ œ๋Š” ํ•ด๋‹น ์•„์ด๋””๋ฅผ ๋ฐ›์•„ @PathVariable๋กœ ์•„์ด๋””๋ฅผ ๋ฐ›์•„ ์‚ญ์ œ ์ง„ํ–‰ ํ›„ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ

  • ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ œ๋ชฉ 1์ด ์ˆ˜์ •๋œ ๊ฑธ ์•Œ ์ˆ˜์žˆ๋‹ค.
  • ์ˆ˜์ •๋œ ๊ฒฐ๊ณผ๋ฌผ ์‚ญ์ œ ์™„๋ฃŒ !!

๋งˆ๋ฌด๋ฆฌ

  • ์ถ”ํ›„์—๋Š” ์ œ๋ชฉ์„ ๊ฒ€์ƒ‰ํ•˜๋ฉด ์„ธ๋ถ€ ๊ฒ€์ƒ‰์œผ๋กœ ๋„˜์–ด๊ฐ€๋Š” ๊ธฐ๋Šฅ๊ณผ ์กฐํšŒ์ˆ˜ ๊ธฐ๋Šฅ ๋Œ€๋Œ“๊ธ€ ๊ธฐ๋Šฅ๊นŒ์ง€ ๊ตฌํ˜„์„ ํ•ด ๋ณผ ๊ฒƒ์ด๋‹ค.. mvc2ํŽธ์„ ๋“ฃ๊ณ  ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ๊ณผ ๊ฒ€์ฆ ๊ธฐ๋Šฅ ๊นŒ์ง€ ..?
profile
์šด๋™๊ณผ ๊ฐœ๋ฐœ ๊ณต๋ถ€ ๋‘˜ ๋‹ค ๋†“์น˜์ง€ ๋ง์ž!

0๊ฐœ์˜ ๋Œ“๊ธ€