pageRequestDTO 를 보내면 pageResultDTO로 받아준다
result.get()하면
반환타입은 list<BoardDTO>
PageRequestDTO pageRequestDTO = new PageRequestDTO();
PageResultDTO<BoardDTO, Object[]> result = boardService.getList(pageRequestDTO);
List<BoardDTO> list = result.getDtoList();
for(BoardDTO dto : list) System.out.println(dto);
이렇게 돌려봤을 때 잘 돌아가는지 확인
BoardService
inferface 에서 메소드 선언하고 Impl에서 실제 구현
//특정 게시글 정보를 가져오는 메소드 선언해서 게시글 번호를 인자로 받아서 BoardDTO 객체를 반환
BoardDTO get(Long bno);
public BoardDTO get(Long bno){
// 의존성 주입을 받은 repository 에게 특정 게시글 정보를 요청
// 얘가 return 하는 값은 여러 객체가 섞여있는 값을 받으니 (sql문에서)
// return은 Object 객체로 받고, Object에는 Board, Member, 댓글수를 저장한 배열이다.
Object result = repository.getBoardByBno(bno);
// 다 담을 수 있는 Object객체로 왔지만 사실은 array임 (Board, Member, 댓글 수)
Object[] arr = (Object[])result; // 그래서 하이캐스팅함 Object[]로 !
BoardDTO dto = convertEntity2DTO((Board)arr[0], (Member)arr[1], (Long)arr[2]);
// arr[0] 이건 Object타입임 그래서 강제로 형변환 해서 보내줘야함
return dto;
}
// 테스트 코드
@Test
public void testGet(){
//의존성 주입받은 BoardService의 get 메소드르 호출한다.
// 그러면 게시글의 정보가 BoardDTO객체로 반한된다.
Long bno = 100L;
BoardDTO dto = boardService.get(bno);
System.out.println(dto);
}
댓글 같이 조회하는 sql 문
select b.title, b.writer_email, r.text
from board b left join reply r on r.board_bno = b.bno
where b.bno = 101;
// inner join하면 나오는 결과가 없는데 left join히면 댓글이 없어도 댓글 칼럼은 null되어 결과가 반환됨
// 왼쪽은 살려주기 때문이다.
// 댓글이 있으면 게시글 삭제를 할 수 없음
// 그래서 테이블 생성할 때 reply 테이블 생성 시 cascade하면 부모가 죽으면(게시글 삭제) 같이 사라진다
// 나중에 이걸 적용하려면 alter해서 reply 테이블을 바꿔주거나 코딩 시 reply을 먼저 다 삭제하고 게시글을 지운다
delete from board where bno = 100;
↓ 이걸 repository로 적용하면
ReplyRepository interface
@Modifying // 이 쿼리를 실행하면 데이터베이스가 변경된다고 알려줌 이걸 안쓰면 오류난다고 함 (select문에는 안씀)
@Query("delete from Reply r where r.board.bno = :bno")
void deleteByBno(Long Bno);
// Reply클래스의 Board타입의 board가 있는데 그 board의 bno값과 비교
// board 에서 관계를 타고 타고 가야하기때문에 굳이 만들어줌
// 그냥 테이블을 삭제하는거면 이미 정의되어 있는거 쓰면 된다
BoardService interface에 removeWithReplies(Long bno) 선언
BoardServiceImpl에서 구현
// 댓글 삭제와 게시글 삭제를 하나의 트랜잭션으로 처리해야함
// 혹시나 댓글만 삭제되면 안되니까 처리를 한번에 묶기 위함
// sql 여러개 실행해야하면 트랜잭션으로 묶자 !
@Transactional // 쪼개질 수 없는 하나의 처리로 묶어서 혹시나 오류가 생기면 모두 취소시켜버림
@Override
public void removeWithReplies(Long bno){
// bno 게시글의 댓글 삭제
// bno 게시글 삭제
// DI받은 BoardRepository, ReplyRepository에게 삭제 요청 (DI = @Autowired하는거)
boardRepository.deleteById(bno);
replyRepository.deleteByBno(bno);
}
변경한 내용을 entity클래스에 반영해서 repository에 전해줘서 DB에 반영해야함
entity클래스에는 setter가 없기때문에 변경할 수 없음
set메소드를 구현하는데 set으로 이름을 지으면 자동으로 원하지 않을때 불려질 수 있기 때문에 이름을 set (X) change로 해서 만든다
entity클래스에 변경할 속성만 setter메소드를 만들어준다
public void changeTitle(String title) {
this.title = title;
}
실제 DB변경은 Repository에 save메소드를 사용한다.
service
//boardDTO 객체를 전달받아 게시글을 수정하는 메소드
@Override
public void modify(BoardDTO boardDTO){
// 로직 설명
// 먼저 BoardRepository에게 변경할 entity 객체를 가져와서
// 변환할 값만 바꾸고 (change메소드로)
// save 수행
Optional<Board> opboard = repository.findById(BoardDTO.getBno());
if(opboard.isPresent()){
Board board = opboard.get();
board.changeTitle(boardDTO.getTitle());
board.chageContent(boardDTO.getContent());
// board객체의 bno 필드값이 이미 설정되어 있기 때문에 삽입이 아니라 갱신이 일어남
// save하기 전에 select해보고 있으면 update, 없으면 insert하기 때문이다
repository.save(entity);
}
}
controller
@Controller
@RequestMapping("/board") // http://localhost:8080/board
public class BoardController{
@Autowired
private BoardService service; // service DI받기
@GetMapping("/list") // http://localhost:8080/board/list
public void list(PageRequestDTO pageRequestDTO, Model model) {
// PageRequestDTO객체로 pagenation정보(page, size정보)를 받는다
// 설정안하면 기본으로 page 1, size 10으로 된다
// 매개변수로 전달받은 JavaBean 객체는 자동으로 Model객체에 들어간다
// model에 addAttribute실행한거랑 똑같은거임(아마 변수이름으로 들어감)
// == model.addAttribute("pageRequestDTO", pageRequestDTO);
// 이걸 생략해도 그냥 자동으로 들어가져있음, 이름을 바꾸고 싶으면 이렇게 함
PageResultDTO<BoardDTO, Object[]> result = service.getList(PageRequestDTO);
// 이건 매개변수로 받은게 아니니까 model에 넣어줌
model.addAttribute("result" , result);
// 그럼 이제 pageRequestDTO 랑 result 두개가 들어가있음
}
}
이렇게 하고 html파일 수정하면 된다
글 등록 controller
* 컨트롤러에서 redirect 시 전달할게 있으면 redirectAttributes를 사용하면 된다
@PostMapping("/register")
public String register(BoardDTO dto, RedirectAttributes re){
Long bno = service.register(dto);
// db 변경을 가한 후 뷰페이지로 연결할때는 forwarding / redirect 하는게 바람직함
// Forwarding할 경우에 뷰페이지에 전달할 정보는 model에 넣어줌
// redirect의 경우, model을 사용할 수 없으니
// RedirectAttributes를 사용해 정보를 넣어주면 된디.
// flash attribute는 오직 한번 리다이렉트되는 뷰 페이지에 전달한다.
// 새로고침하거나 하면 안보내짐
re.addFlashAttribute("msg", bno);
return "redirect:/board/list";
}
* redirection시 addAttribute는 객체로 전달하면 안된다 따로 빼서 스트링으로 보내야함 ! 그래야
msg=bno&page=1 이런식으로 보낼 수 있음!
restful service에서는 api단에서 post put get delete 요청을 보낼 수 있는데
웹브라우저는 post, get 요청밖에 없다 !
스프링 프로젝트 기동 오류 (0) | 2022.01.14 |
---|---|
[spring] 용어 - 계속 추가할 예정 (0) | 2022.01.13 |
[spring] BoardService 목록 처리 (0) | 2021.04.13 |
[spring] MVC - 프로젝트 구조 및 환경 (1) | 2021.01.26 |
[spring] 스프링 프로젝트 생성하기 (0) | 2021.01.25 |