답글 작성을 위해서 새 엔티티 생성 -> BOARD 엔티티의 BNO를 외부키로 가져옴 (답글 엔티티 기준 ManyToOne) -> 답글작성
- 외래키를 엔티티로 가져온다는 뜻은 모든 데이터를 가져오는것이 아니라 엔티티 형태의 기본키 컬럼만 가져오는것이고, 타입은 BIGINT로 잡힌다.
BOARD10의 모든것을 가져오는것이 아님, 즉, BOARD10의 PK인 BNO만 가져온다.
- 외부키로 BoardEntity 전체가 들어오는 모양이지만 DB에서는 BNO만 가져오고, BOARD의 타입은 BIGINT로 잡힌다. (위 이미지 참고)
package com.example.entity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.CreationTimestamp;
import org.springframework.format.annotation.DateTimeFormat;
import lombok.Data;
@Entity
@Data
@Table(name = "BOARD10_REPLY")
// 생성할 시퀀스
@SequenceGenerator(name = "SQE1", sequenceName = "SEQ_BOARD10_REPLY_RNO", allocationSize = 1, initialValue = 1)
public class BoardReplyEntity {
@Id
@Column(name = "RNO")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SQE1")
private long no;
@Column(name = "RCONTENT", length = 300)
private String content;
@Column(name = "RWRITER", length = 50)
private String writer;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
@CreationTimestamp
@Column(name = "RREGDATE")
private Date date;
// 외부키, 보드 자체가 들어오는 개념
@ManyToOne
@JoinColumn(name = "BOARD")
private BoardEntity board;
}
- BoardEntity에도 BoardReplyEntity와의 관계를 정의하고, List의 형태로 해당 PK에 속한 BoardReplyEntity들을 담는다.
: BoardEntity의 입장에서는 OneToMany의 관계
: 12번글에 적힌 댓글 2개를 replyList라는 객체명에 List의 형태로 담는것
package com.example.entity;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.CreationTimestamp;
import org.springframework.format.annotation.DateTimeFormat;
import lombok.Data;
@Entity
@Data
// 테이블명
@Table(name = "BOARD10")
// 시퀀스 생성
@SequenceGenerator(name = "SEQ_BOARD", // 시퀀스
sequenceName = "SEQ_BOARD10_NO", // 시퀀스명
allocationSize = 1, // 증가값
initialValue = 1) // 시작값
public class BoardEntity {
@Id
@Column(name = "BNO") // 컬럼명
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_BOARD") // 시퀀스 적용
private Long no; // 타입 변수
@Column(name = "BTITLE", length = 200) // VARCHAR2(200)
private String title = null;
@Lob // CLOB
@Column(name = "BCONTENT")
private String content;
@Column(name = "BWRITER")
private String writer;
@Column(name = "BHIT")
private long hit = 1L;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
@CreationTimestamp // CURRENT_DATE
@Column(name = "BREGDATE")
private Date regdate;
// BOARD10 입장에서는 OneToMany
// 만약 10번글에 답글이 세개가 달렸다면,
// 답글들은 10번이라는 외부키를 받을것이고,
// 10번 글은 답글의 PK인 no를 List로 가진다.
@OneToMany(mappedBy = "board")
private List<BoardReplyEntity> replyList = new ArrayList<>();
}
답글 작성을 위해서 새 엔티티 생성 -> BOARD 엔티티의 BNO를 외부키로 가져옴 (답글 엔티티 기준 ManyToOne) -> 답글작성
package com.example.repository;
import java.util.List;
import com.example.entity.BoardReplyEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface BoardReplyRepository extends JpaRepository<BoardReplyEntity, Long> {
// 원본글번호가 일치하는 댓글 개수
// List<BoardReplyEntity> replyList = new ArrayList<>();
// Board안에 no를 객체로 잡을때는 언더바_를 사용한다
List<BoardReplyEntity> findByBoard_noOrderByNoDesc(long bno);
}
package com.example.controller;
import java.util.List;
import com.example.entity.BoardEntity;
import com.example.entity.BoardReplyEntity;
import com.example.repository.BoardReplyRepository;
import com.example.repository.BoardRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping(value = "/board")
public class BoardController {
// global.properties 사용
@Value("${board.page.count}")
int PAGECNT;
@Autowired
BoardRepository bRepository;
@Autowired
BoardReplyRepository brRepository;
// 답글 POST
@PostMapping(value = "/insertreply")
public String insertReplyPOST(
@ModelAttribute BoardReplyEntity reply) {
System.out.println("=== reply === " + reply);
System.out.println("=== reply.toString() === " + reply.toString());
brRepository.save(reply);
return "redirect:/board/selectone?no=" + reply.getBoard().getNo();
}
// 추가 GET
@GetMapping(value = { "/insert" })
public String insertGET() {
return "board/insert";
}
// 추가 POST
@PostMapping(value = "/insert")
public String insertPOST(
@ModelAttribute BoardEntity board) {
// save(entity객체) == INSERT INTO
bRepository.save(board);
return "redirect:/board/insert";
}
// 목록 GET
@GetMapping(value = "/selectlist")
public String selectlistGET(Model model,
@RequestParam(value = "txt", defaultValue = "") String title,
@RequestParam(value = "page", defaultValue = "1") int page) {
// 페이지네이션
// (시작페이지(0부터), 개수)
PageRequest pageRequest = PageRequest.of(page - 1, PAGECNT);
// findAll == SELECT * FROM BOARD10
// List<BoardEntity> list = bRepository.selectBoardList(title);
List<BoardEntity> list = bRepository.findByTitleContainsOrderByNoDesc(title, pageRequest);
model.addAttribute("list", list);
// 페이지개수
long total = bRepository.countByTitleContaining(title);
model.addAttribute("pages", (total - 1) / PAGECNT + 1);
// System.out.println("=== list === " + list);
return "board/selectlist";
}
// 상세 GET
@GetMapping(value = "/selectone")
public String selectoneGET(Model model,
@RequestParam(name = "no") long no) {
BoardEntity board = bRepository.findById(no).orElse(null);
// 댓글 개수
List<BoardReplyEntity> repList = brRepository.findByBoard_noOrderByNoDesc(board.getNo());
model.addAttribute("repList", repList);
model.addAttribute("board", board);
// System.out.println("=== board === " + board);
return "board/selectone";
}
}