미니 프로젝트/게시판

[Java] 게시판 ⑤ Repository(service) ⓐ

웹개발자(진) 2024. 5. 23. 16:12
반응형
잡담

Repository(service)에서는 게시판에서 기본적으로 사용하는 입력하고, 삭제하고, 검색하는 메서드를 정의합니다. 해당 메서드들을 Controller에서 데이터를 주고받을 때 호출해서 사용할 겁니다.

1. BoardService

package org.zerock.b01.service;

import org.zerock.b01.dto.BoardDTO;
import org.zerock.b01.dto.PageRequestDTO;
import org.zerock.b01.dto.PageResponseDTO;

public interface BoardService {
    Long register(BoardDTO boardDTO);
    BoardDTO readOne(Long bno);
    void modify(BoardDTO boardDTO);
    void remove(Long bno);
    PageResponseDTO<BoardDTO> list(PageRequestDTO pageRequestDTO);
}

 

  • register(BoardDTO boardDTO): 새로운 게시글을 등록합니다. 등록된 게시글의 ID를 반환합니다.
    • BoardDTO를 매개변수로받아 게시글에 필요한 작성자, 제목, 내용 등을 받아올 수 있습니다.
  • readOne(Long bno): 주어진 ID를 가진 게시글을 조회하여 반환합니다.
    • 하나의 게시글만 조회합니다. primarykey인 bno를 매개변수로받아서 해당 게시글만 불러옵니다.
  • modify(BoardDTO boardDTO): 주어진 게시글 정보를 기반으로 게시글을 수정합니다.
    • 하나의 게시글을 수정합니다. BoardDTO를 받아와서 출력하고 수정하고싶은 부분만 수정해서 돌려줍니다.
  • remove(Long bno): 주어진 ID를 가진 게시글을 삭제합니다.
    • 게시글을 삭제합니다. primarykey인 bno를 매개변수로받아서 해당 게시글만 삭제합니다.
  • list(PageRequestDTO pageRequestDTO): 페이지 요청 정보를 기반으로 게시글 목록을 조회하여 반환합니다. 페이징 처리된 목록을 반환합니다.
    • PageRequestDTO에 있는 페이지 정보와 현재링크주소 정보 등을 받습니다. 해당내용을 PageResponseDTO에서 받아 Controller에서 사용합니다.

 

 


 

BoardService에서 정의한 변수들의 복잡한 코딩들은 BoardServiceImpl에서 사용해 보겠습니다.

Service에서는 기본적으로 DTO의 형식을 통해 html에서 입력받은 데이터를 데이터베이스에 맞게 Mapping 해주는 역할과 Mapping 된 데이터를 메서드를 통해서 DB에 적용시키는 동작을 합니다.

2. BoardServiceImpl

package org.zerock.b01.service;

import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.zerock.b01.domain.Board;
import org.zerock.b01.dto.BoardDTO;
import org.zerock.b01.dto.PageRequestDTO;
import org.zerock.b01.dto.PageResponseDTO;
import org.zerock.b01.repository.BoardRepository;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Transactional
public class BoardServiceImpl implements BoardService{

    private final ModelMapper modelMapper;
    private final BoardRepository boardRepository;

    @Override
    public Long register(BoardDTO boardDTO){
        Board board = modelMapper.map(boardDTO, Board.class);
        Long bno = boardRepository.save(board).getBno();
        return bno;
    }

    @Override
    public BoardDTO readOne(Long bno){
        Optional<Board> result = boardRepository.findById(bno);
        Board board = result.orElseThrow();
        BoardDTO boardDTO = modelMapper.map(board, BoardDTO.class);
        return boardDTO;
    }

    @Override
    public void modify(BoardDTO boardDTO){
        Optional<Board> result = boardRepository.findById(boardDTO.getBno());
        Board board = result.orElseThrow();
        board.change(boardDTO.getTitle(), boardDTO.getContent());
        boardRepository.save(board);
    }

    @Override
    public void remove(Long bno){
        boardRepository.deleteById(bno);
    }

    @Override
    public PageResponseDTO<BoardDTO> list(PageRequestDTO pageRequestDTO){
        String[] types = pageRequestDTO.getTypes();
        String keyword = pageRequestDTO.getKeyword();
        Pageable pageable = pageRequestDTO.getPageable("bno");

        Page<Board> result = boardRepository.searchAll(types, keyword, pageable);

        List<BoardDTO> dtoList = result.getContent().stream()
                .map(board -> modelMapper.map(board, BoardDTO.class))
                .collect(Collectors.toList());

        return PageResponseDTO.<BoardDTO>withAll()
                              .pageRequestDTO(pageRequestDTO)
                              .dtoList(dtoList)
                              .total((int)result.getTotalElements())
                              .build();
    }
}

위의 코드들을 읽어보시면 Controller에서 나중에 호출하는 메서드들입니다. JPARepository에 기본적으로 존재하는 메서드들을 사용해서 save, delete 등을 하는 것을 알 수 있고, 기본적인 메서드들로만은 해결할 수 없는 query 같은 경우는 (list메서드) boardRepository에 상속받은 BoardSearch에 존재하는 메서드를 사용합니다. 여기서는 searchAll을 통해서 검색기능과 page정보를 받아오는 것을 볼 수 있습니다.

 


1. 등록(register)

 @Override
    public Long register(BoardDTO boardDTO){
        Board board = modelMapper.map(boardDTO, Board.class);
        Long bno = boardRepository.save(board).getBno();
        return bno;

해당 코드는 html을 통해 입력받은 데이터를 BoardDTO형태로 매개변수로 받아와서 board Entity에 맞게 Mapping 하여 save메서드를 통해 DB에 추가하는 코드입니다. 여기서 return의 형태로 Long 타입인 bno를 던져주는데 사실 void로 두고 return을 없애도 문제는 없습니다. 

return으로 bno를 받은 이유는 나중에 Controller에서 해당 return값을 사용해서 view 단에 등록이 되었다는 메시지를 던져주기 위해서입니다. 

 


2. 출력(readOne)

@Override
    public BoardDTO readOne(Long bno){
        Optional<Board> result = boardRepository.findById(bno);
        Board board = result.orElseThrow();
        BoardDTO boardDTO = modelMapper.map(board, BoardDTO.class);
        return boardDTO;
    }

해당코드는 여러 게시물 중 선택한 하나의 게시물만 출력하는 메서드입니다. 게시판에 게시물 중에 하나를 선택했을 때 Controller를 통해 해당게시물의 자세한 내용이 담겨있는 URL로 이동하여 출력합니다. Primarykey인 Long 타입의 bno를 매개변수로 받아 findById를 통해 해당값을 받아옵니다.

Optional

은 값이 존재할 수도 있고 존재하지 않을 수도 있는 상황을 나타내며, null 값으로 인한 오류를 피하고 더 명시적인 코드를 작성하는 데 도움이 됩니다. 데이터가 null값이 넘어가면 보통 NullPointException 에러가 뜹니다. Optional을 뜨면 해당 예외처리를 알아서 해줍니다. 예외처리가 된 result값에 필요한 board부분만 orElseThrow 메서드를 통해서 board변수에 가져옵니다.

findById

findById 메서드는 Spring Data JPA에서 제공하는 기본 메서드로, 데이터베이스에서 특정 엔터티를 고유 ID로 조회할 때 사용됩니다. 이 메서드는 JpaRepository 인터페이스에 정의되어 있습니다. findById는 주어진 ID에 해당하는 엔터티를 조회하여 Optional로 반환합니다. 매개변수로 받은 bno를 이용해서 해당 Board클래스 값을 받아옵니다.

 


3. 수정(Modify)

@Override
    public void modify(BoardDTO boardDTO){
        Optional<Board> result = boardRepository.findById(boardDTO.getBno());
        Board board = result.orElseThrow();
        board.change(boardDTO.getTitle(), boardDTO.getContent());
        boardRepository.save(board);
    }

게시판에서 수정하는 방법에 대해 생각해 봅시다. 수정할 때 register와 같이 빈 공간에 새로 다 타이핑하지 않습니다. 이전에 작성했던 내용들을 불러오고 해당내용을 수정해서 DB에 전달합니다.

그래서 BoardDTO 매개변수를 받아와서 그중에 getBno를 통해 수정할 하나의 게시글을 선택하고 Optional <Board>를 통해 예외처리를 해주고 orElseThrow메서드를 통해서 예외처리된 데이터중 Board값만 가져옵니다. 

2024.05.16 - [미니 프로젝트/게시판] - [Java] 게시판 ② DB구성

 

[Java] 게시판 ② DB구성

잡담게시판 미니프로젝트를 실행할 때 가장 먼저 구상한 것은 DB에 어떤 데이터를 담을 것인가입니다. 후에 제대로 된 프로젝트를 진행한다면 다양한 데이터를 담겠지만 지금은 기능을 구현하

gustjr7532.tistory.com

앞서서 Entity를 작성할 때 change 메서드를 통해서 바뀔 값들을 미리지정 해주었습니다. 게시글의 제목인 title과 게시글의 내용인 content를 매개변수로 받아 초기화합니다. change메서드를 사용해서 getTitle, getContent를 통해 매개변수로 받은 board에서 꺼내옵니다. 수정이 완료된 값을 save 메서드를 통해 저장합니다.

 


4. 삭제(remove)

@Override
    public void remove(Long bno){
        boardRepository.deleteById(bno);
    }

 

삭제만큼 간단한 것도 없습니다. 삭제하고자 하는 게시글의 primarykey인 Long 타입의 bno를 매개변수로 받아. deleteById메서드를 사용하여 삭제합니다.

deleteById는 Spring Data JPA에서 제공하는 메서드로, 데이터베이스에서 특정 엔티티를 삭제할 때 사용됩니다. 이 메서드는 주로 Repository 인터페이스에서 사용되며, 엔티티의 ID를 기반으로 해당 엔티티를 삭제합니다.

 


 

글을 마치며

JPARepository에서 기본적으로 가지고 있는 Save, deleteById, findById 등을 이용해서 간단한 게시글 등록, 수정, 삭제를 해보았습니다. JpaRepository 인터페이스를 확장하기만 하면 Spring Data JPA가 기본 CRUD 메서드를 구현해 줍니다. 내용을 찾고 싶은데 간단한 select문으로는 찾을 수 없는 구조적으로 복잡한 내용이면 어떻게 해야 할까요? 그럴 때 사용하는 게 queryDsl입니다. 

아직 하나 남은 게 있습니다. 변수명을 list로 준 PageResponseDTO <BoardDTO> 리스트입니다. 해당내용은 다음 게시글에서 다루도록 하겠습니다. 

반응형