스프링부트 강좌 54강(블로그 프로젝트) - 글목록보기
index로 갈때, 즉 메인 페이지로 왔을 때 데이터를 가져와야 한다. 스프링에서는 데이터를 가져갈 때 모델이 필요하다.
BoardController.java
package com.yuri.blog.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.yuri.blog.config.auth.PrincipalDetail;
import com.yuri.blog.service.BoardService;
@Controller
public class BoardController {
@Autowired
private BoardService boardService;
// 컨트롤로에서 세션을 어떻게 찾는지?
// @AuthenticationPrincipal PrincipalDetail principal
@GetMapping({"", "/"})
public String index(Model model) {
model.addAttribute("boards",boardService.글목록());
return "index";
}
// User 권한이 필요
@GetMapping("/board/saveForm")
public String saveForm() {
return "board/saveForm";
}
}
누가 슬러시 주소를 요청하면 모델에 글 목록을 다 들고온다. findAll()함수를 이용하면 모두 들고올 수 있다.
BoardService.java
package com.yuri.blog.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.yuri.blog.model.Board;
import com.yuri.blog.model.RoleType;
import com.yuri.blog.model.User;
import com.yuri.blog.repository.BoardRepository;
import com.yuri.blog.repository.UserRepository;
@Service
public class BoardService {
@Autowired
private BoardRepository boardRepository;
@Transactional
public void 글쓰기(Board board, User user) { // title, content
board.setCount(0);
board.setUser(user);
boardRepository.save(board);
}
public List<Board> 글목록() {
return boardRepository.findAll();
}
}
boardRepository 가 findAll이라는 함수를 들고 있기 때문이다.
BoardRepository.java
package com.yuri.blog.repository;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import com.yuri.blog.model.Board;
import com.yuri.blog.model.User;
public interface BoardRepository extends JpaRepository<Board, Integer>{
}
BoardRepository.java 에 가면 아무런 함수도 없지만 JPARepository가 다 들고 있다.
layout/header.jsp 에 jstl이 필요하다.
컨트롤러에서
@GetMapping({"", "/"})
public String index(Model model) {
model.addAttribute("boards",boardService.글목록());
return "index";
}
boards 가 넘어오는데 index라는 페이지로boards가 날라간다. BoardController는 일반적인 RestController가 아니라 Controller이기 때문에 retrun 할때 viewResolver라는 게 작동한다. 얘가 작동하면 해당 인덱스 페이지로 모델의 정보를 들고 이동한다.
viewResolver라는 얘는 리턴값 인덱스 앞뒤에
prefix: /WEB-INF/views/ #controller가 return 할 때 앞에 붙여주는 경로명 suffix: .jsp # 뒤에 붙여주는 경로명
모델은 jsp에서는 request 정보라고 생각하면 된다. 모델에다가 데이터를 담으면 view까지 데이터를 끌고 이동한다. 이 데이터는 컬렉션이다. 컬렉션을 가지고 인덱스 페이지로 가니까 itmes에서 받을 수 있다. 받아서 한건씩 board라는 변수에 집어넣어 뿌릴 수 있다.
board라는 객체가 title라는 변수를 하나 들고 있다. 모델에 보면....
실제로는 getTitle이라는 메서드가 호출된다. model에서 우리는 이미 @Data를 이용하여 getter, setter를 만들어주었다.
package com.yuri.blog.model;
import java.sql.Timestamp;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.CreationTimestamp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder //빌더 패턴
@Entity //orm, 데이터베이스에 맵핑을 시켜주는 클래스이다라고 명시해주는 어노테이션을 가까이 명시하는 게 좋음
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) //auto_increment
private int id;
@Column(nullable = false, length=100)
private String title;
@Lob //대용량 데이터를 사용할 떄
private String content; // 섬머노트 라이브러리 <html>태그가 섞여서 디자인이 됨
private int count; // 조회수
@ManyToOne(fetch = FetchType.EAGER) //Many = Board, User = One
@JoinColumn(name="userId") //실제로 db에 만들어질 때는 userId라는 이름으로 만들어 질 것이다.
private User user; //DB는 오브젝트를 저장할 수 없다. FK, 자바는 오브젝트를 저장할 수 있다.
@OneToMany(mappedBy = "board", fetch = FetchType.EAGER) //mappedBy 연관관계의 주인이 아니다. (난 FK가 아니다). DB에 컬럼을 만들지 마시오.
private List<Reply> reply;
@CreationTimestamp
private Timestamp createDate;
}
index.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<%@ include file="layout/header.jsp"%>
<div class="container">
<c:forEach var="board" items="${boards}">
<div class="card m-2">
<div class="card-body">
<h4 class="card-title">${board.title}</h4>
<a href="#" class="btn btn-primary">상세보기</a>
</div>
</div>
</c:forEach>
</div>
<%@ include file="layout/footer.jsp"%>
${board.title} 는 사실 board.getTitle이 호출되는 것...
다음과 같이 글 목록이 보여진다 😁😁😁😁
-이 글은 유투버 겟인데어의 스프링 부트 강좌를 바탕으로 정리한 내용입니다.-