[Spring Boot]/[JPA]
[JPA] 벡엔드 (02_SimpleDMS_Page) 반응형 게시판
북방바다코끼리표범
2023. 11. 2. 21:56
벡엔드 순서
ReplyBoard.java -> ReplyBoardRepository.java-> ReplyBoardDto -> ReplyBoardService.java
-> ReplyBoardController.java
ReplyBoard.java
|
package com.example.simpledms.model.entity.normal; |
|
|
|
import com.example.simpledms.model.common.BaseTimeEntity; |
|
import lombok.*; |
|
import org.hibernate.annotations.DynamicInsert; |
|
import org.hibernate.annotations.DynamicUpdate; |
|
import org.hibernate.annotations.SQLDelete; |
|
import org.hibernate.annotations.Where; |
|
|
|
import javax.persistence.*; |
|
|
|
/** |
|
* packageName : com.example.simpledms.model.entity.normal |
|
* fileName : ReplyBoard |
|
* author : GGG |
|
* date : 2023-10-26 |
|
* description : |
|
* 요약 : |
|
* <p> |
|
* =========================================================== |
|
* DATE AUTHOR NOTE |
|
* ————————————————————————————— |
|
* 2023-10-26 GGG 최초 생성 |
|
*/ |
|
@Entity |
|
@Table(name="TB_REPLY_BOARD") |
|
@SequenceGenerator( |
|
name = "SQ_REPLY_BOARD_GENERATOR" |
|
, sequenceName = "SQ_REPLY_BOARD" |
|
, initialValue = 1 |
|
, allocationSize = 1 |
|
) |
|
@Getter |
|
@Setter |
|
@ToString |
|
@Builder |
|
@NoArgsConstructor |
|
@AllArgsConstructor |
|
@DynamicInsert |
|
@DynamicUpdate |
|
// soft delete |
|
@Where(clause = "DELETE_YN = 'N'") |
|
@SQLDelete(sql = "UPDATE TB_REPLY_BOARD SET DELETE_YN = 'Y', DELETE_TIME=TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') WHERE BID = ?") |
|
public class ReplyBoard extends BaseTimeEntity { |
|
|
|
// 속성 |
|
@Id |
|
@GeneratedValue(strategy = GenerationType.SEQUENCE |
|
, generator = "SQ_REPLY_BOARD_GENERATOR") |
|
private Integer bid; // 기본키, 시퀀스 |
|
|
|
private String boardTitle; |
|
|
|
private String boardContent; |
|
|
|
private String boardWriter; |
|
|
|
private Integer viewCnt; |
|
|
|
private Integer boardGroup; // 트리구조 최상위 부모 노드( 부모가 있을 경우 : 부모번호, 없을 경우 : 자신의 게시판번호 )(정렬) |
|
|
|
private Integer boardParent; // 자신의 부모 노드 ( 부모가 있을 경우 : 부모번호, 없을 경우 : 0 ) : 핵심 |
|
} |
ReplyBoardRepository.java
|
package com.example.simpledms.model.entity.normal; |
|
|
|
import com.example.simpledms.model.common.BaseTimeEntity; |
|
import lombok.*; |
|
import org.hibernate.annotations.DynamicInsert; |
|
import org.hibernate.annotations.DynamicUpdate; |
|
import org.hibernate.annotations.SQLDelete; |
|
import org.hibernate.annotations.Where; |
|
|
|
import javax.persistence.*; |
|
|
|
/** |
|
* packageName : com.example.simpledms.model.entity.normal |
|
* fileName : ReplyBoard |
|
* author : GGG |
|
* date : 2023-10-26 |
|
* description : |
|
* 요약 : |
|
* <p> |
|
* =========================================================== |
|
* DATE AUTHOR NOTE |
|
* ————————————————————————————— |
|
* 2023-10-26 GGG 최초 생성 |
|
*/ |
|
@Entity |
|
@Table(name="TB_REPLY_BOARD") |
|
@SequenceGenerator( |
|
name = "SQ_REPLY_BOARD_GENERATOR" |
|
, sequenceName = "SQ_REPLY_BOARD" |
|
, initialValue = 1 |
|
, allocationSize = 1 |
|
) |
|
@Getter |
|
@Setter |
|
@ToString |
|
@Builder |
|
@NoArgsConstructor |
|
@AllArgsConstructor |
|
@DynamicInsert |
|
@DynamicUpdate |
|
// soft delete |
|
@Where(clause = "DELETE_YN = 'N'") |
|
@SQLDelete(sql = "UPDATE TB_REPLY_BOARD SET DELETE_YN = 'Y', DELETE_TIME=TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') WHERE BID = ?") |
|
public class ReplyBoard extends BaseTimeEntity { |
|
|
|
// 속성 |
|
@Id |
|
@GeneratedValue(strategy = GenerationType.SEQUENCE |
|
, generator = "SQ_REPLY_BOARD_GENERATOR") |
|
private Integer bid; // 기본키, 시퀀스 |
|
|
|
private String boardTitle; |
|
|
|
private String boardContent; |
|
|
|
private String boardWriter; |
|
|
|
private Integer viewCnt; |
|
|
|
private Integer boardGroup; // 트리구조 최상위 부모 노드( 부모가 있을 경우 : 부모번호, 없을 경우 : 자신의 게시판번호 )(정렬) |
|
|
|
private Integer boardParent; // 자신의 부모 노드 ( 부모가 있을 경우 : 부모번호, 없을 경우 : 0 ) : 핵심 |
|
} |
ReplyBoardDto
|
package com.example.simpledms.model.dto.normal; |
|
|
|
/** |
|
* packageName : com.example.simpledms.model.dto.normal |
|
* fileName : ReplyBoardDto |
|
* author : GGG |
|
* date : 2023-10-26 |
|
* description : 계층형 쿼리 DTO |
|
* 요약 : |
|
* <p> |
|
* =========================================================== |
|
* DATE AUTHOR NOTE |
|
* ————————————————————————————— |
|
* 2023-10-26 GGG 최초 생성 |
|
*/ |
|
public interface ReplyBoardDto { |
|
// 속성 x => getter 함수 |
|
public Integer getBid(); |
|
public String getBoardTitle(); |
|
public String getBoardContent(); |
|
public String getBoardWriter(); |
|
public Integer getViewCnt(); |
|
public Integer getBoardGroup(); |
|
public Integer getBoardParent(); |
|
} |
ReplyBoardService.java
|
package com.example.simpledms.service.normal; |
|
|
|
import com.example.simpledms.model.dto.normal.ReplyBoardDto; |
|
import com.example.simpledms.model.entity.normal.ReplyBoard; |
|
import com.example.simpledms.repository.normal.ReplyBoardRepository; |
|
import org.springframework.beans.factory.annotation.Autowired; |
|
import org.springframework.data.domain.Page; |
|
import org.springframework.data.domain.Pageable; |
|
import org.springframework.stereotype.Service; |
|
|
|
import java.util.Optional; |
|
|
|
/** |
|
* packageName : com.example.simpledms.service.normal |
|
* fileName : ReplyBoardService |
|
* author : GGG |
|
* date : 2023-10-26 |
|
* description : |
|
* 요약 : |
|
* <p> |
|
* =========================================================== |
|
* DATE AUTHOR NOTE |
|
* ————————————————————————————— |
|
* 2023-10-26 GGG 최초 생성 |
|
*/ |
|
@Service |
|
public class ReplyBoardService { |
|
|
|
@Autowired |
|
ReplyBoardRepository replyBoardRepository; |
|
|
|
// 계층형 쿼리 조회(dto) : like 검색 |
|
public Page<ReplyBoardDto> selectByConnectByPage(String boardTitle, Pageable pageable) { |
|
|
|
Page<ReplyBoardDto> page |
|
= replyBoardRepository.selectByConnectByPage(boardTitle, pageable); |
|
|
|
return page; |
|
} |
|
|
|
// 답변 글 저장 |
|
public ReplyBoard save(ReplyBoard replyBoard) { |
|
ReplyBoard replyBoard2 = replyBoardRepository.save(replyBoard); |
|
|
|
return replyBoard2; |
|
} |
|
|
|
// 게시물 저장 |
|
public int saveBoard(ReplyBoard replyBoard) { |
|
int insertCount |
|
= replyBoardRepository.insertByBoard(replyBoard); |
|
|
|
return insertCount; |
|
} |
|
|
|
// 상세조회 함수 |
|
public Optional<ReplyBoard> findById(int bid) { |
|
Optional<ReplyBoard> optionalReplyBoard |
|
= replyBoardRepository.findById(bid); |
|
|
|
return optionalReplyBoard; |
|
} |
|
|
|
// 답변만 삭제 |
|
public boolean removeById(int bid) { |
|
if (replyBoardRepository.existsById(bid)) { // bid 있는지 확인 |
|
replyBoardRepository.deleteById(bid); // 삭제 진행 |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
|
|
// 게시물 + 답변 2개이상 삭제 |
|
public boolean removeAllByBoardGroup(int boardGroup) { |
|
|
|
int deleteCount = replyBoardRepository.removeAllByBoardGroup(boardGroup); |
|
|
|
if (deleteCount > 0) { |
|
return true; |
|
} else { |
|
return false; |
|
} |
|
} |
|
} |
ReplyBoardController
|
package com.example.simpledms.controller.normal; |
|
|
|
import com.example.simpledms.model.dto.normal.ReplyBoardDto; |
|
import com.example.simpledms.model.entity.basic.Dept; |
|
import com.example.simpledms.model.entity.normal.ReplyBoard; |
|
import com.example.simpledms.service.normal.ReplyBoardService; |
|
import lombok.extern.slf4j.Slf4j; |
|
import org.springframework.beans.factory.annotation.Autowired; |
|
import org.springframework.data.domain.Page; |
|
import org.springframework.data.domain.PageRequest; |
|
import org.springframework.data.domain.Pageable; |
|
import org.springframework.http.HttpStatus; |
|
import org.springframework.http.ResponseEntity; |
|
import org.springframework.web.bind.annotation.*; |
|
|
|
import java.util.HashMap; |
|
import java.util.Map; |
|
import java.util.Optional; |
|
|
|
/** |
|
* packageName : com.example.simpledms.controller.normal |
|
* fileName : ReplyBoardController |
|
* author : GGG |
|
* date : 2023-10-26 |
|
* description : |
|
* 요약 : |
|
* <p> |
|
* =========================================================== |
|
* DATE AUTHOR NOTE |
|
* ————————————————————————————— |
|
* 2023-10-26 GGG 최초 생성 |
|
*/ |
|
@Slf4j |
|
@RestController |
|
@RequestMapping("/api/normal") |
|
public class ReplyBoardController { |
|
|
|
@Autowired |
|
ReplyBoardService replyBoardService; |
|
|
|
// 전체 조회(계층형, dto) : like 검색 |
|
@GetMapping("/reply-board") |
|
public ResponseEntity<Object> selectByConnectByPage( |
|
@RequestParam(defaultValue = "") String boardTitle, |
|
@RequestParam(defaultValue = "0") int page, |
|
@RequestParam(defaultValue = "3") int size |
|
) { |
|
try { |
|
Pageable pageable = PageRequest.of(page, size); |
|
|
|
Page<ReplyBoardDto> replyBoardDtoPage |
|
= replyBoardService |
|
.selectByConnectByPage(boardTitle, pageable); |
|
|
|
Map<String, Object> response = new HashMap<>(); |
|
response.put("replyBoard", replyBoardDtoPage.getContent()); // 배열 |
|
response.put("currentPage", replyBoardDtoPage.getNumber()); // 현재페이지번호 |
|
response.put("totalItems", replyBoardDtoPage.getTotalElements()); // 총건수(개수) |
|
response.put("totalPages", replyBoardDtoPage.getTotalPages()); // 총페이지수 |
|
|
|
if (replyBoardDtoPage.isEmpty() == false) { |
|
// 성공 |
|
return new ResponseEntity<>(response, HttpStatus.OK); |
|
} else { |
|
// 데이터 없음 |
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT); |
|
} |
|
} catch (Exception e) { |
|
log.debug(e.getMessage()); |
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); |
|
} |
|
} |
|
|
|
// 답변글 저장 |
|
@PostMapping("/reply") |
|
public ResponseEntity<Object> create(@RequestBody ReplyBoard replyBoard) { |
|
|
|
try { |
|
ReplyBoard replyBoard2 = replyBoardService.save(replyBoard); // db 저장 |
|
|
|
return new ResponseEntity<>(replyBoard2, HttpStatus.OK); |
|
} catch (Exception e) { |
|
// DB 에러가 났을경우 : INTERNAL_SERVER_ERROR 프론트엔드로 전송 |
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); |
|
} |
|
} |
|
|
|
// 게시물 저장 |
|
@PostMapping("/reply-board") |
|
public ResponseEntity<Object> createBoard(@RequestBody ReplyBoard replyBoard) { |
|
|
|
try { |
|
int insertCount = replyBoardService.saveBoard(replyBoard); // db 저장 |
|
|
|
return new ResponseEntity<>(insertCount, HttpStatus.OK); |
|
} catch (Exception e) { |
|
// DB 에러가 났을경우 : INTERNAL_SERVER_ERROR 프론트엔드로 전송 |
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); |
|
} |
|
} |
|
|
|
// 수정함수 |
|
@PutMapping("/reply-board/{bid}") |
|
public ResponseEntity<Object> update( |
|
@PathVariable int bid, |
|
@RequestBody ReplyBoard replyBoard) { |
|
|
|
try { |
|
ReplyBoard replyBoard2 = replyBoardService.save(replyBoard); // db 수정 |
|
|
|
return new ResponseEntity<>(replyBoard2, HttpStatus.OK); |
|
} catch (Exception e) { |
|
// DB 에러가 났을경우 : INTERNAL_SERVER_ERROR 프론트엔드로 전송 |
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); |
|
} |
|
} |
|
|
|
// 상세조회 |
|
@GetMapping("/reply-board/{bid}") |
|
public ResponseEntity<Object> findById(@PathVariable int bid) { |
|
|
|
try { |
|
// 상세조회 실행 |
|
Optional<ReplyBoard> optionalReplyBoard = replyBoardService.findById(bid); |
|
|
|
if (optionalReplyBoard.isPresent()) { |
|
// 성공 |
|
return new ResponseEntity<>(optionalReplyBoard.get(), HttpStatus.OK); |
|
} else { |
|
// 데이터 없음 |
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT); |
|
} |
|
} catch (Exception e) { |
|
// 서버 에러 |
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); |
|
} |
|
} |
|
|
|
|
|
// 답변만 삭제 |
|
@DeleteMapping("/reply/deletion/{bid}") |
|
public ResponseEntity<Object> delete(@PathVariable int bid) { |
|
|
|
// 프론트엔드 쪽으로 상태정보를 보내줌 |
|
try { |
|
// 삭제함수 호출 |
|
boolean bSuccess = replyBoardService.removeById(bid); |
|
|
|
if (bSuccess == true) { |
|
// delete 문이 성공했을 경우 |
|
return new ResponseEntity<>(HttpStatus.OK); |
|
} |
|
// delete 실패했을 경우( 0건 삭제가 될경우 ) |
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT); |
|
} catch (Exception e) { |
|
// DB 에러가 날경우 |
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); |
|
} |
|
} |
|
|
|
// 게시물 + 답변 2개이상 삭제 |
|
@DeleteMapping("/reply-board/deletion/{boardGroup}") |
|
public ResponseEntity<Object> deleteBoard(@PathVariable int boardGroup) { |
|
|
|
// 프론트엔드 쪽으로 상태정보를 보내줌 |
|
try { |
|
// 삭제함수 호출 |
|
boolean bSuccess = replyBoardService.removeById(boardGroup); |
|
|
|
if (bSuccess == true) { |
|
// delete 문이 성공했을 경우 |
|
return new ResponseEntity<>(HttpStatus.OK); |
|
} |
|
// delete 실패했을 경우( 0건 삭제가 될경우 ) |
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT); |
|
} catch (Exception e) { |
|
// DB 에러가 날경우 |
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); |
|
} |
|
} |
|
|
|
} |