자유 게시판 기능부터 구현해보도록 하겠다.
상대적으로 ,, 간단해보인다,,,
우선 값 검증이나 이런것들은 한번에 하겠다.
참고로 제대로 동작하는지 위해 다음과 같이 임시 데이터를 넣어줬다.
(@PostConstruct 사용)

@MappedSuperclass
@Getter
@EntityListeners(AuditingEntityListener.class)
public class BaseTimeEntity {
  @CreatedDate
  @Column(updatable = false)
  private LocalDateTime createdDate; // 등록일
  @LastModifiedDate
  private LocalDateTime lastModifiedDate; // 수정일
  @PrePersist
  public void prePersist() {
    LocalDateTime now = LocalDateTime.now();
    createdDate = now;
    lastModifiedDate = now;
  }
  @PreUpdate
  public void preUpdate(){
    LocalDateTime now = LocalDateTime.now();
    lastModifiedDate = now;
  }
}
@Entity @Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Table(name = "users")
public class User extends BaseTimeEntity {
  @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "user_id")
  private Long id;
  private String name; // 본명
  private String nickname; // 별명
  private String password;
  private String email;
  @Builder
  public User(String name, String nickname, String password, String email) {
    this.name = name;
    this.nickname = nickname;
    this.password = password;
    this.email = email;
  }
  public void update(UserUpdateRequestDto updateDto) {
    // 갑자기 궁금한게 회원정보를 닉네임만 변경하던가 비번만 변경할 수 있는데 이럴경우 업데이트 메서드를 따로 분리해야하나?
    this.nickname = updateDto.getNickname();
    this.password = updateDto.getPassword();
  }
}
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Board extends BaseTimeEntity {
  @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String title;
  @Lob
  private String content;
  @ManyToOne(fetch = FetchType.EAGER)
  @JoinColumn(name = "user_id")
  private User user;
  public void setUser(User user){ 
    this.user = user;
  }
  public void update(BoardUpdateRequestDto request) {
    this.title = request.getTitle();
    this.content = request.getContent();
  }
}
@Repository
public interface BoardRepository extends JpaRepository<Board, Long> {
  Page<Board> findAll(Pageable pageable);
}
@Service
@RequiredArgsConstructor
public class BoardService {
  private final BoardRepository boardRepository;
  // 게시판 등록
  public Long save(BoardSaveRequestDto request, User user){
    Board board = request.toEntity();
    board.setUser(user);
    boardRepository.save(board);
    return board.getId();
  }
  // 게시판 조회 - 단건
  public BoardResponseDto findById(Long id){
    Board board = boardRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("존재하지 않는 포스트입니다."));
    return new BoardResponseDto(board);
  }
  // 게시판 조회 - 전체
  public List<BoardResponseDto> findAll() {
    List<BoardResponseDto> boards = boardRepository.findAll()
        .stream()
        .map(BoardResponseDto::new)
        .collect(Collectors.toList());
    return boards;
  }
  // 게시판 조회 - 전체, 페이징 적용
  public Page<BoardResponseDto> findAll(Pageable pageable) {
    Page<BoardResponseDto> boards = boardRepository.findAll(pageable).map(BoardResponseDto::new);
    return boards;
  }
  // 회원 삭제
  public void delete(Long id){
    boardRepository.deleteById(id);
  }
  // 게시판 수정
  @Transactional
  public void update(Long id, BoardUpdateRequestDto request){
    Board board = boardRepository.findById(id)
        .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 포스트입니다."));
    board.update(request);
  }
}
package com.jiwon.blog.web.controller.view;
import com.jiwon.blog.domain.user.User;
import com.jiwon.blog.repository.UserRepository;
import com.jiwon.blog.service.BoardService;
import com.jiwon.blog.web.dto.board.BoardResponseDto;
import com.jiwon.blog.web.dto.board.BoardSaveRequestDto;
import com.jiwon.blog.web.dto.board.BoardUpdateRequestDto;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpSession;
import java.util.List;
@Controller
@RequiredArgsConstructor
public class BoardViewController {
  private final BoardService boardService;
  // 글 등록 폼 보여주기
  @GetMapping("/board/form")
  public String boardWrite(Model model){
    model.addAttribute("boardSaveRequestDto", new BoardSaveRequestDto());
    return "board/form";
  }
  // 글 등록
  @PostMapping("/board/form")
  public String boardSave(@ModelAttribute BoardSaveRequestDto boardSaveRequestDto, HttpSession session){
    User loginUser = (User) session.getAttribute("loginUser");
    boardService.save(boardSaveRequestDto, loginUser);
    return  "redirect:/boards";
  }
  // 글 조회 - 단건 = 상세 조회
  @GetMapping("/boards/{id}")
  public String boards(@PathVariable Long id, Model model) {
    BoardResponseDto board = boardService.findById(id);
    model.addAttribute("board", board);
    return "board/detailBoard";
  }
  // 글 조회 - 전체 - 페이징
  @GetMapping("/boards")
  public String boards(Model model,
                       @PageableDefault(size = 5, sort = "createdDate",
                           direction = Sort.Direction.DESC) Pageable pageable) {
    Page<BoardResponseDto> boards = boardService.findAll(pageable);
    model.addAttribute("boards", boards);
    return "board/main";
  }
  // 글 삭제
  @DeleteMapping("/boards/{id}")
  public String delete(@PathVariable Long id){
    boardService.delete(id);
    return "redirect:/boards";
  }
  // 글 수정 폼
  @GetMapping("/boards/{id}/edit")
  public String updateForm(@PathVariable Long id, Model model){
    BoardResponseDto board = boardService.findById(id);
    BoardUpdateRequestDto boardUpdateRequestDto = new BoardUpdateRequestDto();
    boardUpdateRequestDto.setTitle(board.getTitle());
    boardUpdateRequestDto.setContent(board.getContent());
    model.addAttribute("boardUpdateRequestDto", new BoardUpdateRequestDto());
    return "board/modifyForm";
  }
  // 글 수정
  @PutMapping("/boards/{id}/edit")
  public String update(@PathVariable Long id,
                       @ModelAttribute BoardUpdateRequestDto boardUpdateRequestDto,
                       @RequestParam(defaultValue = "/") String redirectURL){
    boardService.update(id, boardUpdateRequestDto);
    return "redirect:/boards/"+id;
  }
}
spring:
 ... 
  mvc:
    hiddenmethod:
      filter:
        enabled: true
짱구로 로그인한 후 테스트 시연이다. (맥북 영상녹화 시프트 + 커맨드 + 숫자 5)
디테일보단 우선 기능위주로,,, UI는 참참참^^