Sparta 내일배움캠프 Java 5기/[13주차] Spring 심화 Team Project ✓
(24.07.11) 칸반보드의 Column 관리 기능 개발
3 Layer Architecture(Controller - Service - Repository) 중 Service 기준
Column 생성, 삭제 기능
// 컬럼 생성
public ColumnInfoResponseDto createColumn(Long boardId,
@Valid ColumnInfoRequestDto columnInfoResponseDto,
User user) {
...
ColumnInfo columnInfo = new ColumnInfo(columnInfoResponseDto, foundBoard);
columnInfo.updatePosition(foundColumnStatuses.size() + 1);
columnsRepository.save(columnInfo);
return new ColumnInfoResponseDto(columnInfo);
}
// 컬럼 삭제
public void deleteColumn(Long boardId, Long columnInfoId, User user) {
...
validateBoardOwnership(boardId, foundUser);
ColumnInfo foundColumn = columnsRepository.findById(columnInfoId).orElseThrow(
() -> new BadRequestException("해당 컬럼은 존재하지 않습니다.")
);
...
columnsRepository.delete(foundColumn);
}
- Column 은 MySQL DB에 저장을 할 때, SQL 쿼리문에 사용되기 때문에 ColumnInfo로 협의하여 엔터티로 지정
- colmnsRepository는 Service 단에서 형태로 생성자 주입을 받아 느슨한 연결로 구성
@Service
@RequiredArgsConstructor
public class ColumnInfoService {
private final ColumnsRepository columnsRepository;
- columnRepository는 interface 로 JpaRepository를 상속 받아, save delete를 @Transactional을 사용하지 않고 자동으로 트랜잭션을 관리할 수 있음
@Repository
public interface ColumnsRepository extends JpaRepository<ColumnInfo, Long> {
Column 순서 변경 기능
Controller
@PostMapping("/manager/boards/{boardId}/columns/{columnsId}/move")
public ResponseEntity<MessageResponse> moveColumn(@PathVariable(name = "boardId") Long boardId,
@PathVariable(name = "columnsId") Long columnInfoId,
@RequestParam(name = "position") Integer newPosition,
@AuthenticationPrincipal UserDetailsImpl userDetails) {
...
- Controller에서 무조건 바꿀 위치 position 을 RequestParam 형식으로 받아, PRD 에서 요구했듯이 유동적으로 작동 될 수 있도록 함
Service
@Transactional
public void moveColumn(Long boardId, Long columnInfoId, Integer newPosition, User user) {
User foundUser = userRepository.findByUsername(user.getUsername()).orElseThrow(
() -> new BadRequestException("해당 사용자는 존재하지 않습니다.")
);
...
List<ColumnInfo> columnList = columnsRepository.findByBoardIdOrderByPosition(boardId);
newPosition = newPosition > columnList.size() ? columnList.size() : newPosition;
foundColumn.updatePosition(newPosition);
Integer position = 1;
for (ColumnInfo column : columnList) {
if (!column.getId().equals(foundColumn.getId())) {
if (position == newPosition) {
position++;
}
column.updatePosition(position);
position++;
}
}
}
- 최대한 성능을 위해 for문을 최소화 할 수 있도록 for 문 하나로 로직을 구성하려고 고민
- 단, 컬럼이 각 보드마다 과도하게 많은 양으로 저장되지 않을 것으로 가정
- 가장 이상적인 알고리즘은 아래와 같으나, for문이 두개를 구성을 해야해서 하나로 만들기 위해 위와 같이 조건으로 옮겨질 Column과 Position을 뛰어넘을 수 있도록 바꿈
- RequestParam으로 받은 Column 이 옮겨질 position을 CurrentPosition으로 지정
- position이 CurrentPosition 이전의 것들을 for문을 돌면서 1부터 부여
- position이 CurrentPosition 이후의 것들을 for문을 돌면서 CurrentPosition 다음부터 부여
- 중간에 하나의 Column이라도 Position이 update 되지 않을 경우 Save 를 모두 Rollback 하기 위해서 @Transactional을 메서드에 사용
- save 도 JpaRepository로 인해서 자동으로 Commit 되지만, 그 상위의 메서드 @Transactional이 되어야 Commit 되기 때문
'Sparta 내일배움캠프 Java 5기 > [13주차] Spring 심화 Team Project ✓' 카테고리의 다른 글
(24.07.16) A08조 "Palette" Project - KPT 회고 (0) | 2024.07.16 |
---|---|
(24.07.15) Card 생성의 동시성 제어 (0) | 2024.07.15 |
(24.07.12) 칸반보드의 Column 관리 기능 Refactor 및 수정, Comment 기능 개발 (0) | 2024.07.12 |
(24.07.10) Project S.A. 작성 (0) | 2024.07.10 |