[Spring Boot/JPA] 게시판을 통해 MVC, CRUD 연습하기 1 - 목록
본문 바로가기

Web 개발/게시판 만들기

[Spring Boot/JPA] 게시판을 통해 MVC, CRUD 연습하기 1 - 목록

728x90
반응형

Spring Boot + H2 Database + JPA + Thymeleaf 을 활용해

간단한 게시판을 작성해보고자 합니다.

오늘은 게시판 글 목록 보여주는 기능입니다.

 

* 개발환경
Spring Boot : 2.4.3
Java 11
Thymeleaf 
Maven
War
Lombok

 

templates 에 List.html 생성

List.html에 작성한 글을 보여줄 테이블 생성

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="contents">
    <table>
        <thead>
        <tr>
            <th class="one wide">번호</th>
            <th class="ten wide">글제목</th>
            <th class="two wide">작성자</th>
            <th class="three wide">작성일</th>
        </tr>
        </thead>

        <tbody>
        <!-- CONTENTS !-->
        <tr th:each="board, index : ${boardList}">
            <td>
                <span th:text="${index.index}"></span>
            </td>
            <td>
                <a th:href="@{'/list/' + ${board.id}}">
                    <span th:text="${board.title}"></span>
                </a>
            </td>
            <td>
                <span th:text="${board.writer}"></span>
            </td>
            <td>
                <span th:text="${#temporals.format(board.createdDate, 'yyyy-MM-dd HH:mm')}"></span>
            </td>
        </tr>
        </tbody>
    </table>
    
</div>

</body>
</html>

 

Java > controller 패키지 하위에 Board Controll 클래스 생성

Board Controller에 list() 메소드 생성

Service를 통해 boardDtoList를 boardList로 넘겨받아서 view에 전달

import com.example.demo.dto.BoardDto;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

@Controller
public class BoardController {

    private BoardService boardService;

    public BoardController(BoardService boardService){
        this.boardService = boardService;
    }

    @GetMapping("/")
    public String list(Model model){
        List<BoardDto> boardDtoList = boardService.getBoardList();
        model.addAttribute("boardList", boardDtoList);
        return "list.html";
    }
    
}

 

Java > service 패키지 하위에 Board Service 클래스 생성

Service 에 getBoardList() 메소드 생성

builder()를 호출하여 DTO object를 생성하고 리턴

package com.example.demo.service;

import com.example.demo.domain.entity.Board;
import com.example.demo.domain.repository.BoardRepository;
import com.example.demo.dto.BoardDto;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class BoardService {

    private BoardRepository boardRepository;

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

    @Transactional
    public List<BoardDto> getBoardList(){
        List<Board> boards = boardRepository.findAll();
        List<BoardDto> boardDtoList = new ArrayList<>();

        for(Board board : boards){
            BoardDto dto = BoardDto.builder()
                    .id(board.getId())
                    .title(board.getTitle())
                    .content(board.getContent())
                    .writer(board.getWriter())
                    .createdDate(board.getCreatedDate())
                    .build();

            boardDtoList.add(dto);
        }
        return boardDtoList;
    }


}

 

Java > dto 패키지 하위에 BoardDto 클래스 생성

Dto 에 BoardDto 생성 후, Lombok를 이용해 @Builder를 추가

package com.example.demo.dto;

import com.example.demo.domain.entity.Board;
import lombok.*;

import java.time.LocalDateTime;

@Setter
@Getter
@ToString
@NoArgsConstructor
public class BoardDto {
    private Long id;
    private String writer;
    private String title;
    private String content;
    private LocalDateTime createdDate;
    private LocalDateTime modifiedDate;

    public Board toEntity(){
        Board build = Board.builder()
                .id(id)
                .writer(writer)
                .title(title)
                .content(content)
                .build();
        return build;
    }

    @Builder
    public BoardDto(Long id, String title, String content, String writer, LocalDateTime createdDate, LocalDateTime modifiedDate){
        this.id = id;
        this.writer = writer;
        this.title = title;
        this.content = content;
        this.createdDate = createdDate;
        this.modifiedDate = modifiedDate;
    }
}

 

Java > entity 패키지 하위에 Board 클래스 생성

Board Entity는 Time Entity를 상속받아, Board 생성 시 생성일과 수정일을 포함하도록 작성

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.NoArgsConstructor;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Board extends TimeEntity{

    @Id
    @GeneratedValue
    private Long id;

    @Column(length = 10, nullable = false)
    private String writer;

    @Column(length = 100, nullable = false)
    private String title;

    @Column(columnDefinition = "TEXT", nullable = false)
    private String content;

    @Builder
    public Board(Long id, String title, String content, String writer){
        this.id = id;
        this.title = title;
        this.content = content;
        this.writer = writer;
    }
}

 

Java > entity 패키지 하위에 TimeEntity 클래스 생성

TimeEntity를 생성하여 Entity 생성 시, 생성일과 수정일 관리

package com.example.demo.domain.entity;

import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class TimeEntity {

    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime modifiedDate;

}

 

6. 마무리

해당 기능을 구현하며 추가로 알게된 내용

- function과 methond 의 차이: 메소드는 클래스에 종속되어있다
- Lombok @builder : Object 생성

 

 

참고 자료: https://velog.io/@max9106/Spring-Boot-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%83%9D%EC%84%B1

728x90
반응형