09009
[Spring Boot] 회원 + 게시판 연습 (3) - 게시글 작성 및 목록 조회 본문
게시판 테이블 설계
BoardDTO 생성
package com.yeongin.boardTest.dto;
import com.yeongin.boardTest.entity.BoardEntity;
import lombok.*;
import java.time.LocalDateTime;
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class BoardDTO {
private Long id;
private Long memberId;
private String title;
private String content;
private int readCount;
private LocalDateTime regDate;
private String writer;
public static BoardDTO toBoardDTO(BoardEntity boardEntity) {
BoardDTO boardDTO = new BoardDTO();
boardDTO.setId(boardEntity.getId());
boardDTO.setTitle(boardEntity.getTitle());
boardDTO.setContent(boardEntity.getContent());
boardDTO.setReadCount(boardEntity.getReadCount());
boardDTO.setRegDate(boardEntity.getRegDate());
boardDTO.setMemberId(boardEntity.getMemberEntity().getId());
boardDTO.setWriter(boardEntity.getMemberEntity().getName());
return boardDTO;
}
}
BoardEntity 생성
package com.yeongin.boardTest.entity;
import com.yeongin.boardTest.dto.BoardDTO;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.lang.reflect.Member;
@Entity
@SequenceGenerator(
name = "board_seq_generator"
, sequenceName = "board_seq"
, initialValue = 1,
allocationSize = 1
)
@Getter
@Setter
@Table(name = "board_table")
public class BoardEntity extends BaseEntity {
@Id
@GeneratedValue(
strategy = GenerationType.SEQUENCE
, generator = "board_seq_generator"
)
private Long id;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String content;
@Column
private int readCount;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private MemberEntity memberEntity;
public static BoardEntity toSaveEntity(BoardDTO boardDTO, MemberEntity memberEntity) {
BoardEntity boardEntity = new BoardEntity();
boardEntity.setId(boardDTO.getId());
boardEntity.setTitle(boardDTO.getTitle());
boardEntity.setContent(boardDTO.getContent());
boardEntity.setReadCount(0);
boardEntity.setMemberEntity(memberEntity);
return boardEntity;
}
}
MemberEntity
코드 추가
@OneToMany(mappedBy = "memberEntity", cascade = CascadeType.REMOVE, orphanRemoval = true, fetch = FetchType.LAZY)
private List<BoardEntity> boardEntityList = new ArrayList<>();
package com.yeongin.boardTest.entity;
import com.yeongin.boardTest.dto.MemberDTO;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@Setter
@SequenceGenerator(
name = "member_seq_generator"
, sequenceName = "member_seq"
, initialValue = 1
, allocationSize = 1
)
@Table(name = "member_table")
public class MemberEntity extends BaseEntity {
@Id
@GeneratedValue(
strategy = GenerationType.SEQUENCE
, generator = "member_seq_generator"
)
private Long id;
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String name;
@OneToMany(mappedBy = "memberEntity", cascade = CascadeType.REMOVE, orphanRemoval = true, fetch = FetchType.LAZY)
private List<BoardEntity> boardEntityList = new ArrayList<>();
public static MemberEntity toMemberEntity(MemberDTO memberDTO) {
MemberEntity memberEntity = new MemberEntity();
memberEntity.setId(memberDTO.getId());
memberEntity.setEmail(memberDTO.getEmail());
memberEntity.setPassword(memberDTO.getPassword());
memberEntity.setName(memberDTO.getName());
return memberEntity;
}
}
board/write.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>글쓰기</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css">
<style>
.orangeButton {
background: #ff6f0f;
font-weight: bold;
color: white;
}
.boardTh {
width: 25%;
background-color : #f4f4f4!important;
}
</style>
</head>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe" crossorigin="anonymous"></script>
<body>
<div class="container">
<div th:include="common/header :: header"></div>
<div class="row mt-5">
<div class="col"></div>
<div class="col-10">
<div class="row mt-2">
<div class="col">
<div class="row fs-4 fw-bold text-center">
<div class="col">
게시글 작성하기
</div>
</div>
<div class="row mt-2">
<div class="col">
<form action="/board/write" method="post">
<input type="hidden" name="memberId" th:value="${session.memberDTO.id}">
<div class="row mt-4 justify-content-center">
<div class="col-10">
<table class="table">
<tr>
<th class="boardTh text-center">제목</th>
<td>
<div class="row">
<div class="col text-start ms-2">
<input type="text" class="form-control"
name="title">
</div>
</div>
</td>
</tr>
<tr>
<th class="boardTh text-center">내용</th>
<td>
<div class="row">
<div class="col text-start ms-2">
<textarea class="form-control" rows="5"
name="content"></textarea>
</div>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="row justify-content-center">
<div class="col-10 text-end">
<button class="btn orangeButton"> 작성하기
<i class="bi bi-pencil-square"></i>
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div class="col"></div>
</div>
</div>
<script th:inline="javascript">
</script>
</body>
</html>
BoardController
@PostMapping("/write")
public String write(@ModelAttribute BoardDTO boardDTO, HttpSession session) {
MemberDTO memberDTO = (MemberDTO) session.getAttribute("memberDTO");
boardService.save(boardDTO, memberDTO.getId());
return "redirect:/";
}
BoardService
package com.yeongin.boardTest.service;
import com.yeongin.boardTest.dto.BoardDTO;
import com.yeongin.boardTest.entity.BoardEntity;
import com.yeongin.boardTest.entity.MemberEntity;
import com.yeongin.boardTest.repository.BoardRepository;
import com.yeongin.boardTest.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class BoardService {
private final MemberRepository memberRepository;
private final BoardRepository boardRepository;
// 게시글 작성
public void save(BoardDTO boardDTO, Long id) {
MemberEntity memberEntity = memberRepository.findById(id).get();
boardRepository.save(BoardEntity.toSaveEntity(boardDTO, memberEntity));
}
BoardRepository
package com.yeongin.boardTest.repository;
import com.yeongin.boardTest.entity.BoardEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface BoardRepository extends JpaRepository<BoardEntity, Long> {
}
게시글 목록 조회
main.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>main</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css">
<style>
.orangeButton {
background: #ff6f0f;
font-weight: bold;
color: white;
}
</style>
</head>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe" crossorigin="anonymous"></script>
<body>
<div class="container">
<div th:include="common/header :: header"></div>
<div class="row mt-5">
<div class="col"></div>
<div class="col-10">
<div class="row mt-2 fs-2 fw-bold">
<div class="col text-center">
Main Page
</div>
</div>
<div class="row mt-3">
<div class="col">
<table class="table">
<tr class="table-secondary text-center">
<th class="col-md-1">번호</th>
<th class="col-md-6">제목</th>
<th class="col-md-2">글쓴이</th>
<th class="col-md-2">날짜</th>
<th class="col-md-1">조회</th>
</tr>
<tr th:each="board: ${boardList}">
<td class="col-md-1 text-center" th:text="${board.id}"></td>
<td class="col-md-6 text-left" th:text="${board.title}"></td>
<td class="col-md-2 text-center" th:text="${board.writer}"></td>
<td class="col-md-2 text-center" th:text="*{#temporals.format(board.regDate, 'yyyy-MM-dd HH:mm:ss')}"></td>
<td class="col-md-1 text-center" th:text="${board.readCount}"></td>
</tr>
</table>
</div>
</div>
<div class="row mt-2 text-end" th:if="${session.memberDTO != null}">
<div class="col">
<button class="btn orangeButton"
onclick="writeBoard()"> 글쓰기
<i class="bi bi-pencil-square"></i>
</button>
</div>
</div>
</div>
<div class="col"></div>
</div>
</div>
<script th:inline="javascript">
const writeBoard = () => {
location.href = "/board/write";
}
</script>
</body>
</html>
BoardDTO
private String writer;
public static BoardDTO toBoardDTO(BoardEntity boardEntity) {
BoardDTO boardDTO = new BoardDTO();
boardDTO.setId(boardEntity.getId());
boardDTO.setTitle(boardEntity.getTitle());
boardDTO.setContent(boardEntity.getContent());
boardDTO.setReadCount(boardEntity.getReadCount());
boardDTO.setRegDate(boardEntity.getRegDate());
boardDTO.setMemberId(boardEntity.getMemberEntity().getId());
boardDTO.setWriter(boardEntity.getMemberEntity().getName());
return boardDTO;
}
HomeController
package com.yeongin.boardTest.controller;
import com.yeongin.boardTest.dto.BoardDTO;
import com.yeongin.boardTest.dto.MemberDTO;
import com.yeongin.boardTest.service.BoardService;
import com.yeongin.boardTest.service.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.ArrayList;
import java.util.List;
@Controller
@RequiredArgsConstructor
public class HomeController {
private final BoardService boardService;
private final MemberService memberService;
@GetMapping("/")
public String main(Model model) {
List<BoardDTO> boardDTOList = boardService.findAll();
model.addAttribute("boardList", boardDTOList);
return "main";
}
BoardService
// 게시글 조회
@Transactional
public List<BoardDTO> findAll() {
List<BoardEntity> boardEntityList = boardRepository.findAll(Sort.by(Sort.Direction.DESC, "id"));
List<BoardDTO> boardDTOList = new ArrayList<>();
for (BoardEntity boardEntity : boardEntityList) {
boardDTOList.add(BoardDTO.toBoardDTO(boardEntity));
}
return boardDTOList;
}
'Back-End > Spring' 카테고리의 다른 글
[Spring Boot] 회원 + 게시판 연습 (5) - 게시글 수정 및 삭제 (0) | 2024.02.05 |
---|---|
[Spring Boot] 회원 + 게시판 연습 (4) - 게시글 상세 조회 (0) | 2024.02.05 |
[Spring Boot] 회원 + 게시판 연습 (2) - 로그인, 회원정보 수정, 로그아웃 (0) | 2024.02.04 |
[Spring Boot] 회원 + 게시판 연습 (1) - 설정 및 회원가입 (0) | 2024.02.03 |
[Spring Boot] 게시판 연습 (10) - 댓글 작성 후 목록 출력 (0) | 2024.01.25 |
Comments