Spring Boot + JPA + Mysql 게시판 (1) 게시글 등록

2023. 1. 7. 23:41checkIn 프로젝트(SpringBoot)

나는 게시글 등록하는 부분을 하기로했다.

 

프로젝트 규모 초기 설정을 너무 크게잡아서 모두가 하기 어렵고

 

불편한 사항이 있을가봐 규모를 축소하고 소규모로 하기로 했다.

 

게시글등록에 관해 작성.

 

1.컨트롤러

package com.teamproject.checkin.board;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.List;

@Controller
@RequiredArgsConstructor
public class BoardController {

    //@Autowired  RequiredArgsConstructor
    //final이 붙거나 @NotNull 이 붙은 필드의 생성자를 자동 생성해주는 롬복 어노테이션
    final BoardService boardService;

    //기본부트스트랩
    @GetMapping("/freeBoard")
    public String FRboardList(Model model){
        List<BoardDto> list = boardService.BoardList();
        model.addAttribute("list",list);
        return "/board/freeBoard";
    }

    @GetMapping("/FRWrite")
    public String FRWrite(Model model){
        return "/board/FRWrite";
    }

    @PostMapping("/boardReg")
    public String boardReg(BoardDto boardDto){
        boardService.boardReg(boardDto);
        return "redirect:/freeBoard";
    }
    @GetMapping("/FRDetail")
    public String FRDetail(Model model){
        return "/board/FRDetail";
    }

    @GetMapping("/FREdit")
    public String FREdit(Model model){
        return "/board/FREdit";
    }

}

FRboardList  : 게시글리스트 (Get)
FRWrite : 게시글 작성화면 (Get)
boardReg : 게시글 입력기능(Post)
FRDetail : 상세조회
FREdit : 수정

 

2.Board (Entity)

package com.teamproject.checkin.board;

import lombok.Getter;
import javax.persistence.*;

@Entity
@Getter
public class Board {

    private String boardType;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)//자동으로 PK 값 입력이 됨 테스트 필요
    private Long boardNo;

    private String boardTitle;
    private String boardContent;
    public Board() { }

    public Board(Long boardNo, String boardType, String boardTitle, String boardContent){
        this.boardNo = boardNo;
        this.boardType = boardType;
        this.boardTitle = boardTitle;
        this.boardContent = boardContent;
    }
    public static Board of (Long boardNo, String boardType, String boardTitle, String boardContent)
    {
        return new Board(boardNo, boardType, boardTitle,boardContent);
    }

}

!!Board of 중요!! JPA를 사용하기 위해 Entity를 리턴해주는 것으로 추측된다.

하단에 내용 설명하도록 하겠습니다.

 

3.BoardRepository

public interface BoardRepository extends JpaRepository<Board, Long> {

}

Repository는 데이터 조작을 담당한다. interface로 생성하며, JpaRepository를 extends한다. JpaRepository의 값은 매핑할 entity와 id의 타입이다.(PK로 추측)

 

4.BoardService

package com.teamproject.checkin.board;

import org.springframework.stereotype.Service;

@Service
public class BoardService {

    private final BoardRepository boardRepository;

    public BoardService(BoardRepository boardRepository) {
        this.boardRepository = boardRepository;
    }

    public Board boardReg(BoardDto dto){
        return boardRepository.save(dto.toEntity());
    }
}

 

Service는 위에서 말했듯 실제로 비즈니스 로직을 시행해주는 역할을 한다.

컨트롤러에서 받은 데이터를 저장히기 위해 BoardService의 boardReg를 실행, boardReg를 구현해줘야한다.

boardReg는 Repository를 통해 실제로 데이터를 저장하게 된다. (repository의 save는 JpaRepository -> PagingAndSortingRepository -> CrudRepository 의 인터페이스이다.)

 

CrudRepository 인터페이스 일부

<S extends T> S save(S entity);

매개변수로 entity를 받는것으로 볼 수 있다.

 

6.DTO

package com.teamproject.checkin.board;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class BoardDto {

    private Long boardNo;
    private String boardType;
    private String boardTitle;
    private String boardContent;

    public BoardDto(Long boardNo, String boardType, String boardTitle, String boardContent) {
        this.boardNo = boardNo;
        this.boardType = boardType;
        this.boardTitle = boardTitle;
        this.boardContent = boardContent;
    }

    public Board toEntity(){
        return  Board.of(boardNo, boardType, boardTitle,boardContent);
    }
}

 

 마지막으로 DTO.

기본 생성자 생성 및  toEntity매서드를 만들어준다.

Board를 Entity로 변환해 주는 기능을 한다. save() 매서드를 사용하기 위함이다.

 

    insert 
    into
        board
        (board_content, board_title, board_type) 
    values
        (?, ?, ?)

 

글 입력시 쿼리가 잘 날아가는것을 볼 수 있다.

 

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
   xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
   layout:decorate="~{layout/layout002}">
<th:block layout:fragment="content002">
<style>
.tbx {
      resize: none;
}
</style>
   <div class="app-content content">
      <div class="content-wrapper">
         <div class="content-wrapper-before"></div>
         <div class="content-header row">
            <div class="content-header-left col-md-4 col-12 mb-2">
               <h3 class="content-header-title">자유게시판</h3> <!-- Title 입력 -->
            </div>
            <div class="content-header-right col-md-8 col-12">
               <div class="breadcrumbs-top float-md-right">
                  <div class="breadcrumb-wrapper mr-1">
                     <ol class="breadcrumb">
                        <li class="breadcrumb-item"><a href="/home">Home</a></li> <!-- Home LINK -->
                        <li class="breadcrumb-item active">자유게시판 > 글쓰기</li> <!-- Title 입력 -->
                     </ol>
                  </div>
               </div>
            </div>
         </div>
         <div class="content-body">
            <section id="chartjs-bar-charts">
               <div class="row">
                  <div class="col-12">
                     <div class="card">
                        <div class="card-header">
                           <h4 class="card-title">자유게시판 게시글작성</h4> <!-- 부제목 입력 -->
                        </div>
                        <div class="card-content collapse show">
                                <div class="row">
                              <div class="col-12">
                                 <div class="card">
                                    <div class="card-header">
                                       <h1 class="card-title"><a href="javascript:history.back()"><span class="pink"><i class="la la-mail-reply"></i>뒤로</span></a></h1>
                                       <a class="heading-elements-toggle"><i class="la la-ellipsis-v font-medium-3"></i></a>
                                       <div class="heading-elements">
                                          <ul class="list-inline mb-0">
                                             <li><a data-action="collapse"><i class="ft-minus"></i></a></li>
                                          </ul>
                                       </div>
                                    </div>
                                    <div class="card-content collapse show">
                                       <div class="card-body">
                                       <form class="form" th:action="@{/boardReg}"  method="post">
                                          <div class="form-body">
                                             <input type="hidden" name="boardType" value="B" readonly>
                                       <!--      <input type="hidden" id="date" name="date">-->
                                             <div class="form-group" style="text-align: right;">
                                                <button type="button" class="btn btn-primary mr-1 btn-sm"><i class="la la-paperclip"></i></button>
                                                <button type="button" class="btn btn-danger mr-1 btn-sm"><i class="la la-file-image-o"></i></button>
                                             </div>
                                             <div class="form-group">
                                                <input type="text" id="writer" class="form-control" placeholder="작성자" name="writer" readonly="readonly" value="작성자">
                                             </div>
                                             <div class="form-group">
                                                <input type="text" id="boardTitle" class="form-control" placeholder="제목을 입력하세요..." name="boardTitle">
                                             </div>
                                             <div class="form-group">
                                                <textarea id="boardContent" name="boardContent" rows="20" class="form-control tbx" placeholder="내용을 입력하세요..." ></textarea>
                                             </div>
                                          </div>
                                          <div class="form-actions center">
                                             <button type="submit" class="btn btn-outline-primary">새글등록</button>
                                          </div>
                                       </form>
                                    </div>
                                    </div>
                                 </div>
                              </div>
                           </div>
                        </div>
                     </div>
                  </div>
               </div>
            </section>
         </div>
      </div>
   </div>
</th:block>
<script>



</script>
</html>

 

현 게시판은 공부중에 작성하는 것으로 많이 미흡한 부분이 있을 수 있습니다.

 

추가내용에 대해서는 추후 추가로 작성하거나 수정하도록하겠습니다.

 

피드백을 주신다면 감사히 받겠습니다

 

(현재 시간이나 작성자 , 게시판타입 등등은 안받거나 하드코딩 입니다)