Board@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Board extends TimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "board_id")
private Long board_id;
@Column(name = "title")
private String title;
@Column(name = "board_content")
private String content;
@Column(name = "writer")
private String writer;
@Enumerated(EnumType.STRING)
private BoardCategory category;
@JsonBackReference
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
}@Enumerated : enum 타입의 프로퍼티 또는 필드를 생성하는 애노테이션입니다.STRING과 ORDINAL이 존재하는데 ORDINAL은 순서, STRING은 글자 그대로이기 때문에 무조건 STRING을 사용하는 것이 좋습니다.User - boards@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User extends TimeEntity {
//...
@JsonManagedReference
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Board> boards = new ArrayList<>();
//...
}@JsonManagedReference - @JsonBackReference를 사용했습니다.@OneToMany - @ManyToOne / @JoinColumn을 사용했습니다. (💡 매우 중요하고 배울 것이 많은 개념이기 때문에 해당 글에서는 생략하겠습니다.)BoardCategorypublic enum BoardCategory {
NORMAL, SPORTS, STYLE, FUN
}BoardRepositorypublic interface BoardRepository extends JpaRepository<Board, Long> {
List<Board> findByCategory(BoardCategory category);
List<Board> findByUser(User user);
}메소드 명, 리턴 타입, 파라미터 등을 사용하여 메소드를 생성할 수 있습니다.findCategory() : 선택한 카테고리에 맞는 게시판의 리스트를 조회할 수 있습니다.findByUser() : 사용자가 작성한 게시글을 리스트로 조회할 수 있습니다.게시판의 작성, 조회, 수정, 삭제를 Spring Data Jpa의
CRUD를 통해 구현합니다.
BoardFindService@Service
@RequiredArgsConstructor
public class BoardFindService {
private final BoardRepository boardRepository;
private final UserFindService userFindService;
@Transactional(readOnly = true)
public Board findById(Long boardId) {
Board board = boardRepository.findById(boardId)
.orElseThrow(() -> new NotFoundBoardException(String.format("Board is not Found!")));
return board;
}
@Transactional(readOnly = true)
public List<Board> findAll() {
return boardRepository.findAll();
}
@Transactional(readOnly = true)
public List<Board> findByCategory(BoardCategory category) {
return boardRepository.findByCategory(category);
}
@Transactional(readOnly = true)
public List<Board> findByUser(Long userId) {
User user = userFindService.findById(userId);
return boardRepository.findByUser(user);
}
}
BoardRepository와 UserFindService를 생성자(@RequiredArgsConstructor + private final)를 통해 참조하도록 합니다.UserFindService를 참조하도록 했습니다.BoardWriteService@Service
@RequiredArgsConstructor
public class BoardWriteService {
private final UserFindService userFindService;
private final BoardRepository boardRepository;
@Transactional
public Long writeBoard(Long userId, BoardWriteRequest boardWriteRequest) {
User user = userFindService.findById(userId);
Board board = Board.builder()
.title(boardWriteRequest.getTitle())
.writer(user.getName())
.content(boardWriteRequest.getContent())
.category(boardWriteRequest.getCategory())
.build();
Board savedBoard = boardRepository.save(board);
user.writeBoard(savedBoard);
return savedBoard.getBoard_id();
}
}
userId와 BoardWriteRequest 입니다.@Getter
@NoArgsConstructor
public class BoardWriteRequest {
private String title;
private String content;
private BoardCategory category;
}id) + builder()를 활용하여 새로운 게시글 생성하여 저장합니다.writeBoard()@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User extends TimeEntity {
//...
public void writeBoard(Board board) {
this.boards.add(board);
board.createdByUser(this);
}
//...
}this.boards.add(board)board.createdByUser(this)@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Board {
//...
public void createdByUser(User user) {
this.user = user; //like setter
}
//...
}BoardUpdateService@Service
@RequiredArgsConstructor
public class BoardUpdateService {
private final UserFindService userFindService;
private final BoardFindService boardFindService;
@Transactional
public Long updateBoard(Long userId, Long boardId, BoardUpdateRequest boardUpdateRequest) {
User user = userFindService.findById(userId);
Board board = boardFindService.findById(boardId);
checkBoardLoginUser(user, board);
Long updatedBoardId = board.update(
boardUpdateRequest.getTitle(),
boardUpdateRequest.getContent(),
boardUpdateRequest.getCategory()
);
return updatedBoardId;
}
private void checkBoardLoginUser(User user, Board board) {
if (!Objects.equals(board.getUser().getUser_id(), user.getUser_id())) {
throw new NotHavePermissionBoardException("해당 게시물을 수정할 권한이 없습니다.");
}
}
}
checkBoardLoginUser)한 후 BoardUpdateRequest를 통해 게시글을 수정할 수 있습니다.@Getter
@NoArgsConstructor
public class BoardUpdateRequest {
private String title;
private String content;
private BoardCategory category;
}BoardDeleteService@Service
@RequiredArgsConstructor
public class BoardDeleteService {
private final UserFindService userFindService;
private final BoardFindService boardFindService;
private final BoardRepository boardRepository;
@Transactional
public void deleteBoardById(Long userId, Long boardId) {
User user = userFindService.findById(userId);
Board board = boardFindService.findById(boardId);
checkBoardLoginUser(user, board);
boardRepository.deleteById(boardId);
}
private void checkBoardLoginUser(User user, Board board) {
if (!Objects.equals(board.getUser().getUser_id(), user.getUser_id())) {
throw new NotHavePermissionBoardException("해당 게시물을 삭제할 권한이 없습니다.");
}
}
}
BoardFindApi@Slf4j
@RestController
@RequestMapping("/boards")
@RequiredArgsConstructor
public class BoardFindApi {
private final BoardFindService boardFindService;
@GetMapping()
public ApiResult<List<Board>> findAll() {
try {
return ApiResult.succeed(boardFindService.findAll());
} catch (Exception e) {
log.error(e.getMessage());
return ApiResult.failed(e.getMessage());
}
}
@GetMapping("/{boardId}")
public ApiResult<Board> findById(@PathVariable Long boardId) {
try {
return ApiResult.succeed(boardFindService.findById(boardId));
} catch (Exception e) {
log.error(e.getMessage());
return ApiResult.failed(e.getMessage());
}
}
@GetMapping("/category/{category}")
public ApiResult<List<Board>> findByCategory(@PathVariable BoardCategory category) {
try {
return ApiResult.succeed(boardFindService.findByCategory(category));
} catch (Exception e) {
log.error(e.getMessage());
return ApiResult.failed(e.getMessage());
}
}
@GetMapping("/user/{userId}")
public ApiResult<List<Board>> findByUserId(@PathVariable Long userId) {
try {
return ApiResult.succeed(boardFindService.findByUser(userId));
} catch (Exception e) {
log.error(e.getMessage());
return ApiResult.failed(e.getMessage());
}
}
}
@(애노테이션) 관련 설명은 User편에서 확인하시길 바랍니다.ApiResult설명 또한, 앞선 게시물에 있습니다!
findAll()findById(Long boardId)findByCategory(BoardCategory boardCategory)findByUserId(Long userId)BoardWriteApi@Slf4j
@RestController
@RequestMapping("/boards")
@RequiredArgsConstructor
public class BoardWriteApi {
private final BoardWriteService boardWriteService;
@PostMapping("/{userId}/write")
public ApiResult<Long> writeBoard(@PathVariable Long userId,
@RequestBody BoardWriteRequest boardWriteRequest) {
try {
Long boardId = boardWriteService.writeBoard(userId, boardWriteRequest);
return ApiResult.succeed(boardId);
} catch (Exception e) {
log.error(e.getMessage());
return ApiResult.failed(e.getMessage());
}
}
}
BoardFindApi와 마찬가지로 해당하는 비즈니스 로직의 서비스 클래스를 사용하여 필요한 정보를 반환하도록 합니다. 특히 try-catch를 사용할 경우, 위처럼 에러를 확인만 하는 행위는 지양해야합니다.BoardUpdateApi와 BoardDeleteApi 또한 필요한 매개변수와 서비스 클래스를 사용하여 비슷하게 구현했기 때문에 생략하겠습니다.
Our Delhi Escort Service is dedicated to providing a truly sexual experience for our clients. Our hot models are carefully selected for their beauty, intelligence, and charm, ensuring that your encounter is not only visually stunning but also intellectually stimulating. Book now and let us show you why we're the best in the business.