본문 바로가기
프로젝트/운동일지

코드리뷰 - 운동관련부분

by 티코딩 2024. 6. 10.

이 프로젝트의 구조는 이렇게 도메인중심으로 짰다.

1. authority는 User의 권한설정 Spring Security 때문에 만들었다.

2. exercise는 운동데이터(세트를 포함), 세트(횟수와 무게를 포함), 운동타입(운동종목)이 존재한다.

3. User에는 User엔터티와, UserPrincipal이 있다.

4. view에는 HomeController, LoginController가 존재한다. 

5. wsession에는 한날짜를 아이디로가지는 운동세션관련 코드가 존재한다.

 

운동관련 엔터티부터 큰순서대로 보자.

wsession 엔터티

@Entity
@Getter
@Setter
@Table(name = "WSESSION")
public class Wsession {
    @Id
    @Column(columnDefinition = "DATE")
    private LocalDate wsessionId;  // 날짜 형식 ID, ex) "20240503"

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id")
    private User user;

    @OneToMany(mappedBy = "wsession", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Exercise> exercises;

}

ID는 LocalDate타입으로 지정해서 한날짜마다 한개의 wsession을 갖게 된다.

그리고 한 유저는 여러개의 wsession을 가질수있어 ManyToOne, 한개의 wsession안에는 여러개의 Exercises를 가질 수 있으니 OneToMany로 지정했다.

 

다음으로 Exercise 엔터티

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Exercise {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long ExerciseId;

    @ManyToOne
    @JoinColumn(name = "wsession_id")
    private Wsession wsession;

    @Enumerated(EnumType.STRING)
    private ExerciseType type;

    @OneToMany(mappedBy = "exercise", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<ExerciseSet> sets;
}

Exercise는 wsession에서 여러개를 가질수있으니 ManyToOne, 운동종목들을 가질 수 있고, 여러개의 세트를 가질 수 있다.

 

다음으로 ExerciseSet

@Entity
@Getter
@Setter
public class ExerciseSet {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long SetId;

    @ManyToOne
    private Exercise exercise;
    @Column
    private int weight;
    @Column
    private int reps;
    @Column
    private int setOrder;
}

세트안에는 무게, 반복횟수, 몇번째 세트인지를 표시하기위한 setOrder이 있다.

 

다음으로는 ExerciseType

public enum ExerciseType {
    SQUATS,
    BENCH_PRESS,
    DEAD_LIFT,
    OVERHEAD_PRESS,
    BARBELL_ROW,
    PULL_UPS,
    DUMBBELL_FLIES,
    LEG_PRESS,
    BICEPS_CURLS,
    TRICEPS_EXTENSIONS
}

운동종목은 나중에 추가만되고 변하지 않아 Enum으로 정의해줬다.

 

처음엔 클라이언트를 따로 만들어서 통신하기 위해 JSON으로 응답하는 api들을 위주로 만들었는데 추후에 웹페이지를 서버에서 만들어서 제공하는 애플리케이션이 되어 점점 바뀌었다.

 

wsessionController

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/wsession")
public class WsessionController {
    private final WsessionService wsessionService;
    private final WsessionRepository wsessionRepository;

    @PostMapping
    public ResponseEntity<?> createSession(@RequestBody WsessionDto.Add sessionDto, @AuthenticationPrincipal UserPrincipal principal) {
        try {
            sessionDto.setUserId(principal.getId());
            WsessionDto.Response sessionResponse = wsessionService.createSession(sessionDto);
            return ResponseEntity.ok(sessionResponse);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error creating session: " + e.getMessage());
        }
    }
    @GetMapping("/{date}")
    public ResponseEntity<WsessionDto.Response> getSession(@PathVariable String date) {
        try {
            LocalDate localDate = LocalDate.parse(date);
            WsessionDto.Response sessionResponse = wsessionService.getSession(localDate);
            return ResponseEntity.ok(sessionResponse);
        } catch (DateTimeParseException e) {
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    @DeleteMapping("/{wsessionId}")
    public ResponseEntity<?> deleteWsession(@PathVariable LocalDate wsessionId) {
        try {
            wsessionService.deleteWsession(wsessionId);
            return ResponseEntity.ok().build();
        } catch (EntityNotFoundException e) {
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error deleting Wsession: " + e.getMessage());
        }
    }

    @PostMapping("/copy")
    public ResponseEntity<?> copyWsession(@RequestBody WsessionDto.WsessionCopyDto copyDto) {
        try {
            WsessionDto.Response newWsession = wsessionService.copyWsession(copyDto.getSourceDate(), copyDto.getTargetDate());
            return ResponseEntity.ok(newWsession);
        } catch (EntityNotFoundException e) {
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error copying Wsession: " + e.getMessage());
        }
    }

}

 

 

 

wsessionService

@Service
@RequiredArgsConstructor
public class WsessionService {

    private final WsessionRepository wsessionRepository;
    private final UserRepository userRepository;

    @Transactional
    public WsessionDto.Response createSession(WsessionDto.Add sessionDto) {
        User user = userRepository.findById(sessionDto.getUserId()).orElseThrow(() -> new RuntimeException("User not found"));
        Wsession session = new Wsession();
        session.setWsessionId(sessionDto.getDate());
        session.setUser(user);
        List<Exercise> exercises = sessionDto.getExerciseTypes().stream()
                .map(type -> {
                    Exercise exercise = new Exercise();
                    exercise.setWsession(session);
                    exercise.setType(type);
                    exercise.setSets(new ArrayList<>()); // 초기 세트 없이 생성
                    return exercise;
                }).collect(Collectors.toList());
        session.setExercises(exercises);
        wsessionRepository.save(session);

        List<WsessionDto.ExerciseDetails> exerciseDetails = exercises.stream()
                .map(exercise -> new WsessionDto.ExerciseDetails(
                        exercise.getExerciseId(),
                        exercise.getType(),
                        exercise.getSets().stream()
                                .map(set -> new WsessionDto.SetDetails(set.getExercise().getExerciseId(), set.getWeight(), set.getReps(),set.getSetOrder()))
                                .collect(Collectors.toList())
                ))
                .collect(Collectors.toList());

        return new WsessionDto.Response(session.getWsessionId(), exerciseDetails);
    }
    public WsessionDto.Response getSession(LocalDate date) {
        Optional<Wsession> sessionOpt = wsessionRepository.findById(date);

        if (!sessionOpt.isPresent()) {
            return null;
        }
        return convertToDto(sessionOpt.get());
    }


    private WsessionDto.Response convertToDto(Wsession session) {
        List<WsessionDto.ExerciseDetails> exercises = session.getExercises().stream()
                .map(exercise -> new WsessionDto.ExerciseDetails(
                        exercise.getExerciseId(),
                        exercise.getType(),
                        exercise.getSets().stream()
                                .map(set -> new WsessionDto.SetDetails(set.getSetId(), set.getWeight(), set.getReps(), set.getSetOrder()))
                                .collect(Collectors.toList())
                ))
                .collect(Collectors.toList());

        return new WsessionDto.Response(session.getWsessionId(), exercises);
    }

    @Transactional
    public void deleteWsession(LocalDate wsessionId) {
        Wsession wsession = wsessionRepository.findById(wsessionId)
                .orElseThrow(() -> new EntityNotFoundException("Wsession not found with date: " + wsessionId));
        wsessionRepository.delete(wsession);
    }
    @Transactional
    public WsessionDto.Response copyWsession(LocalDate sourceDate, LocalDate targetDate) {
        Wsession sourceSession = wsessionRepository.findById(sourceDate)
                .orElseThrow(() -> new EntityNotFoundException("Source Wsession not found"));

        Wsession newSession = new Wsession();
        newSession.setWsessionId(targetDate);
        newSession.setUser(sourceSession.getUser());  // Assuming the same user

        List<Exercise> copiedExercises = sourceSession.getExercises().stream()
                .map(exercise -> {
                    Exercise newExercise = new Exercise();
                    newExercise.setType(exercise.getType());
                    newExercise.setWsession(newSession);
                    newExercise.setSets(exercise.getSets().stream().map(set -> {
                        ExerciseSet newSet = new ExerciseSet();
                        newSet.setWeight(set.getWeight());
                        newSet.setReps(set.getReps());
                        newSet.setExercise(newExercise);
                        newSet.setSetOrder(set.getSetOrder());
                        return newSet;
                    }).collect(Collectors.toList()));
                    return newExercise;
                }).collect(Collectors.toList());

        newSession.setExercises(copiedExercises);
        wsessionRepository.save(newSession);

        return convertToResponseDto(newSession);
    }

    private WsessionDto.Response convertToResponseDto(Wsession session) {
        List<WsessionDto.ExerciseDetails> exerciseDetails = session.getExercises().stream()
                .map(exercise -> new WsessionDto.ExerciseDetails(
                        exercise.getExerciseId(),
                        exercise.getType(),
                        exercise.getSets().stream()
                                .map(set -> new WsessionDto.SetDetails(set.getExercise().getExerciseId(), set.getWeight(), set.getReps(), set.getSetOrder()))
                                .collect(Collectors.toList())
                ))
                .collect(Collectors.toList());

        return new WsessionDto.Response(session.getWsessionId(), exerciseDetails);
    }
    public List<LocalDate> getSessionDates(int year, int month) {
        YearMonth yearMonth = YearMonth.of(year, month);
        LocalDate startDate = yearMonth.atDay(1);
        LocalDate endDate = yearMonth.atEndOfMonth();

        return wsessionRepository.findAllByWsessionIdBetween(startDate, endDate)
                .stream()
                .map(Wsession::getWsessionId)
                .collect(Collectors.toList());
    }
    @Transactional(readOnly = true)
    public WsessionDto.WsessionStatsDto getMonthlyStats(Long userId, YearMonth yearMonth) {
        LocalDate startDate = yearMonth.atDay(1);
        LocalDate endDate = yearMonth.atEndOfMonth();

        List<Wsession> sessions = wsessionRepository.findAllByUserIdAndWsessionIdBetween(userId, startDate, endDate);

        int totalWeight = 0;
        int totalReps = 0;

        for (Wsession session : sessions) {
            for (Exercise exercise : session.getExercises()) {
                for (ExerciseSet set : exercise.getSets()) {
                    totalWeight += set.getWeight();
                    totalReps += set.getReps();
                }
            }
        }
        int totalVolume = totalWeight * totalReps;
        return new WsessionDto.WsessionStatsDto(totalVolume);
    }
}

 

컨트롤러와 서비스를 같이 붙혀서 하나씩 설명해보겠다.

 

1. 운동세션 생성 api

//컨트롤러
@PostMapping
    public ResponseEntity<?> createSession(@RequestBody WsessionDto.Add sessionDto, @AuthenticationPrincipal UserPrincipal principal) {
        try {
            sessionDto.setUserId(principal.getId());
            WsessionDto.Response sessionResponse = wsessionService.createSession(sessionDto);
            return ResponseEntity.ok(sessionResponse);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error creating session: " + e.getMessage());
        }
    }
//서비스
@Transactional
    public WsessionDto.Response createSession(WsessionDto.Add sessionDto) {
        User user = userRepository.findById(sessionDto.getUserId()).orElseThrow(() -> new RuntimeException("User not found"));
        Wsession session = new Wsession();
        session.setWsessionId(sessionDto.getDate());
        session.setUser(user);
        List<Exercise> exercises = sessionDto.getExerciseTypes().stream()
                .map(type -> {
                    Exercise exercise = new Exercise();
                    exercise.setWsession(session);
                    exercise.setType(type);
                    exercise.setSets(new ArrayList<>()); // 초기 세트 없이 생성
                    return exercise;
                }).collect(Collectors.toList());
        session.setExercises(exercises);
        wsessionRepository.save(session);

        List<WsessionDto.ExerciseDetails> exerciseDetails = exercises.stream()
                .map(exercise -> new WsessionDto.ExerciseDetails(
                        exercise.getExerciseId(),
                        exercise.getType(),
                        exercise.getSets().stream()
                                .map(set -> new WsessionDto.SetDetails(set.getExercise().getExerciseId(), set.getWeight(), set.getReps(),set.getSetOrder()))
                                .collect(Collectors.toList())
                ))
                .collect(Collectors.toList());

        return new WsessionDto.Response(session.getWsessionId(), exerciseDetails);
    }

서비스의 createSession을 보면, 먼저 사용자부터 검증하고, Wsession의 객체를 하나 만들고 새로운 객체에다 정보를 집어넣고 저장한다. 만든 exercises를 response에 담기위해 exercsieDetails를 정의한다.

컨트롤러에서는 검증된 사용자의 아이디를 가져와서 서비스를 호출한다.

 

2. 운동세션 불러오는 api

//컨트롤러
@GetMapping("/{date}")
    public ResponseEntity<WsessionDto.Response> getSession(@PathVariable String date) {
        try {
            LocalDate localDate = LocalDate.parse(date);
            WsessionDto.Response sessionResponse = wsessionService.getSession(localDate);
            return ResponseEntity.ok(sessionResponse);
        } catch (DateTimeParseException e) {
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
 //서비스
 public WsessionDto.Response getSession(LocalDate date) {
        Optional<Wsession> sessionOpt = wsessionRepository.findById(date);

        if (!sessionOpt.isPresent()) {
            return null;
        }
        return convertToDto(sessionOpt.get());
    }

만든 세션을 불러오는 api. 날짜(운동세션의 ID)를 파라미터로 받아 있으면 불러오고 없으면 null을 반환함.

 

3. 운동세션 삭제 api

//컨트롤러
@DeleteMapping("/{wsessionId}")
    public ResponseEntity<?> deleteWsession(@PathVariable LocalDate wsessionId) {
        try {
            wsessionService.deleteWsession(wsessionId);
            return ResponseEntity.ok().build();
        } catch (EntityNotFoundException e) {
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error deleting Wsession: " + e.getMessage());
        }
    }
//서비스
@Transactional
    public void deleteWsession(LocalDate wsessionId) {
        Wsession wsession = wsessionRepository.findById(wsessionId)
                .orElseThrow(() -> new EntityNotFoundException("Wsession not found with date: " + wsessionId));
        wsessionRepository.delete(wsession);
    }

날짜형식의 wsessionId를 입력받아서 있으면 삭제한다.

 

4. 운동세션 복사 api

//컨트롤러
@PostMapping("/copy")
    public ResponseEntity<?> copyWsession(@RequestBody WsessionDto.WsessionCopyDto copyDto) {
        try {
            WsessionDto.Response newWsession = wsessionService.copyWsession(copyDto.getSourceDate(), copyDto.getTargetDate());
            return ResponseEntity.ok(newWsession);
        } catch (EntityNotFoundException e) {
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error copying Wsession: " + e.getMessage());
        }
    }
//서비스
@Transactional
    public WsessionDto.Response copyWsession(LocalDate sourceDate, LocalDate targetDate) {
        Wsession sourceSession = wsessionRepository.findById(sourceDate)
                .orElseThrow(() -> new EntityNotFoundException("Source Wsession not found"));

        Wsession newSession = new Wsession();
        newSession.setWsessionId(targetDate);
        newSession.setUser(sourceSession.getUser());

        List<Exercise> copiedExercises = sourceSession.getExercises().stream()
                .map(exercise -> {
                    Exercise newExercise = new Exercise();
                    newExercise.setType(exercise.getType());
                    newExercise.setWsession(newSession);
                    newExercise.setSets(exercise.getSets().stream().map(set -> {
                        ExerciseSet newSet = new ExerciseSet();
                        newSet.setWeight(set.getWeight());
                        newSet.setReps(set.getReps());
                        newSet.setExercise(newExercise);
                        newSet.setSetOrder(set.getSetOrder());
                        return newSet;
                    }).collect(Collectors.toList()));
                    return newExercise;
                }).collect(Collectors.toList());

        newSession.setExercises(copiedExercises);
        wsessionRepository.save(newSession);

        return convertToResponseDto(newSession);
    }
	private WsessionDto.Response convertToResponseDto(Wsession session) {
        List<WsessionDto.ExerciseDetails> exerciseDetails = session.getExercises().stream()
                .map(exercise -> new WsessionDto.ExerciseDetails(
                        exercise.getExerciseId(),
                        exercise.getType(),
                        exercise.getSets().stream()
                                .map(set -> new WsessionDto.SetDetails(set.getExercise().getExerciseId(), set.getWeight(), set.getReps(), set.getSetOrder()))
                                .collect(Collectors.toList())
                ))
                .collect(Collectors.toList());

        return new WsessionDto.Response(session.getWsessionId(), exerciseDetails);
    }

웨이트 트레이닝을 할 때 전의 운동세션을 그대로 하는 경우가 많다. 그럴경우 사용하기 위해 만든 api이다.

서비스로직을 보면 sourceDate:운동세션을 복사할날짜, targetDate:복사한 운동세션을 붙혀넣을 날짜. 

먼저 복사할 날짜에 운동세션이 있는지 체크하고, 있으면 targetDate에 새로운 운동세션을 만들어서 갖고온 데이터를 다 집어넣는다.

그리고 response를 위해 convertToResponseDto를 호출한다.

 

그다음 view쪽에서 wsession과 관련된 코드를 보자.

 

homeController

@GetMapping("/wsession/{date}")
    public String getSessionView(@PathVariable String date, Model model) {
        try {
            LocalDate localDate = LocalDate.parse(date);
            WsessionDto.Response sessionResponse = wsessionService.getSession(localDate);

            if (sessionResponse == null) {
                model.addAttribute("date", localDate);
                return "addExercise";
            } else {
                model.addAttribute("date", localDate);
                model.addAttribute("wsession", sessionResponse);
                return "viewSession";
            }
        } catch (DateTimeParseException e) {
            model.addAttribute("error", "Invalid date format");
            return "error";
        } catch (Exception e) {
            model.addAttribute("error", "An error occurred while fetching the session");
            return "error";
        }
    }
    @GetMapping("/wsession/{date}/addExercise")
    public String addExercise(@PathVariable String date, Model model) {
        model.addAttribute("date", date);
        return "addExercise";
    }

 

위의 getSessionView부터 보면, 파라미터로 받은 문자열 date를 LocalDate타입으로 파싱한뒤 DB에서 해당 날짜의 운동세션을 가져온다. 없으면 addExercise.html을 불러오고, 있으면 viewSession.html을 불러온다. 밑에 addExercise api는 해당날짜에 이미 운동세션이 존재할때 추가적으로 다른 운동을 추가하고싶을때 사용한다.

addExercise.html

 

viewSession.html

ExerciseController

@RestController
@RequestMapping("api/v1/exercises")
@RequiredArgsConstructor
public class ExerciseController {

    private final ExerciseService exerciseService;

    @PostMapping("/{exerciseId}/sets")
    public ResponseEntity<?> addExerciseSet(@PathVariable Long exerciseId, @RequestBody ExerciseSetDto.AddSets exerciseSetDto) {
        try {
            System.out.println("Received request to add set for exerciseId: " + exerciseId);
            ExerciseSet exerciseSet = exerciseService.addExerciseSet(exerciseId, exerciseSetDto);

            Map<String, String> response = new HashMap<>();
            response.put("message", "세트추가가 완료되었습니다.");

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, String> errorResponse = new HashMap<>();
            errorResponse.put("error", "Error adding exercise set: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
        }
    }


    @PatchMapping("/sets/{setId}")
    public ResponseEntity<ExerciseSetDto.Response> updateExerciseSet(@PathVariable Long setId, @RequestBody ExerciseSetDto.UpdateSets updateDto) {
        try {
            ExerciseSetDto.Response updatedSet = exerciseService.updateExerciseSet(setId, updateDto);
            return ResponseEntity.ok(updatedSet);
        } catch (EntityNotFoundException e) {
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    @DeleteMapping("/sets/{setId}")
    public ResponseEntity<?> deleteSet(@PathVariable Long setId) {
        try {
            exerciseService.deleteExerciseSet(setId);
            return ResponseEntity.ok().build();
        } catch (EntityNotFoundException e) {
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error deleting exercise: " + e.getMessage());
        }
    }


    @DeleteMapping("/{exerciseId}")
    public ResponseEntity<?> deleteExercise(@PathVariable Long exerciseId) {
        try {
            exerciseService.deleteExercise(exerciseId);
            return ResponseEntity.ok().build();
        } catch (EntityNotFoundException e) {
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error deleting exercise: " + e.getMessage());
        }
    }
}

 

ExerciseService

@Service
@RequiredArgsConstructor
public class ExerciseService {

    private final ExerciseRepository exerciseRepository;
    private final ExerciseSetRepository exerciseSetRepository;

    @Transactional
    public ExerciseSet addExerciseSet(Long exerciseId, ExerciseSetDto.AddSets exerciseSetDto) {
        Exercise exercise = exerciseRepository.findById(exerciseId)
                .orElseThrow(() -> new RuntimeException("Exercise not found"));
        int currentSetCount = exercise.getSets().size();
        ExerciseSet exerciseSet = new ExerciseSet();
        exerciseSet.setExercise(exercise);
        exerciseSet.setWeight(exerciseSetDto.getWeight());
        exerciseSet.setReps(exerciseSetDto.getReps());
        exerciseSet.setSetOrder(currentSetCount + 1);
        return exerciseSetRepository.save(exerciseSet);
    }

    @Transactional
    public ExerciseSetDto.Response updateExerciseSet(Long setId, ExerciseSetDto.UpdateSets updateDto) {
        ExerciseSet exerciseSet = exerciseSetRepository.findById(setId)
                .orElseThrow(EntityNotFoundException::new);

        if (updateDto.getWeight() != null) {
            exerciseSet.setWeight(updateDto.getWeight());
        }
        if (updateDto.getReps() != null) {
            exerciseSet.setReps(updateDto.getReps());
        }
        exerciseSetRepository.save(exerciseSet);
        return new ExerciseSetDto.Response(exerciseSet.getSetId(), exerciseSet.getWeight(), exerciseSet.getReps(),exerciseSet.getSetOrder());
    }

    @Transactional
    public void deleteExercise(Long exerciseId) {
        Exercise exercise = exerciseRepository.findById(exerciseId)
                .orElseThrow(() -> new EntityNotFoundException("Exercise not found with id: " + exerciseId));

        exerciseRepository.delete(exercise);
    }
    @Transactional
    public void deleteExerciseSet(Long setId) {
        ExerciseSet exerciseSet = exerciseSetRepository.findById(setId)
                .orElseThrow(() -> new EntityNotFoundException("Exercise not found with id: " + setId));

        exerciseSetRepository.delete(exerciseSet);
    }
}

 

1. 세트추가 api

//컨트롤러
@PostMapping("/{exerciseId}/sets")
    public ResponseEntity<?> addExerciseSet(@PathVariable Long exerciseId, @RequestBody ExerciseSetDto.AddSets exerciseSetDto) {
        try {
            System.out.println("Received request to add set for exerciseId: " + exerciseId);
            ExerciseSet exerciseSet = exerciseService.addExerciseSet(exerciseId, exerciseSetDto);

            Map<String, String> response = new HashMap<>();
            response.put("message", "세트추가가 완료되었습니다.");

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, String> errorResponse = new HashMap<>();
            errorResponse.put("error", "Error adding exercise set: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
        }
    }
//서비스    
@Transactional
    public ExerciseSet addExerciseSet(Long exerciseId, ExerciseSetDto.AddSets exerciseSetDto) {
        Exercise exercise = exerciseRepository.findById(exerciseId)
                .orElseThrow(() -> new RuntimeException("Exercise not found"));
        int currentSetCount = exercise.getSets().size();
        ExerciseSet exerciseSet = new ExerciseSet();
        exerciseSet.setExercise(exercise);
        exerciseSet.setWeight(exerciseSetDto.getWeight());
        exerciseSet.setReps(exerciseSetDto.getReps());
        exerciseSet.setSetOrder(currentSetCount + 1);
        return exerciseSetRepository.save(exerciseSet);
    }

 

 

2. 세트수정 api

//컨트롤러
@PatchMapping("/sets/{setId}")
    public ResponseEntity<ExerciseSetDto.Response> updateExerciseSet(@PathVariable Long setId, @RequestBody ExerciseSetDto.UpdateSets updateDto) {
        try {
            ExerciseSetDto.Response updatedSet = exerciseService.updateExerciseSet(setId, updateDto);
            return ResponseEntity.ok(updatedSet);
        } catch (EntityNotFoundException e) {
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
//서비스
@Transactional
    public ExerciseSetDto.Response updateExerciseSet(Long setId, ExerciseSetDto.UpdateSets updateDto) {
        ExerciseSet exerciseSet = exerciseSetRepository.findById(setId)
                .orElseThrow(EntityNotFoundException::new);

        if (updateDto.getWeight() != null) {
            exerciseSet.setWeight(updateDto.getWeight());
        }
        if (updateDto.getReps() != null) {
            exerciseSet.setReps(updateDto.getReps());
        }
        exerciseSetRepository.save(exerciseSet);
        return new ExerciseSetDto.Response(exerciseSet.getSetId(), exerciseSet.getWeight(), exerciseSet.getReps(),exerciseSet.getSetOrder());
    }

 

 

 

3. 세트삭제 api

//컨트롤러
@DeleteMapping("/sets/{setId}")
    public ResponseEntity<?> deleteSet(@PathVariable Long setId) {
        try {
            exerciseService.deleteExerciseSet(setId);
            return ResponseEntity.ok().build();
        } catch (EntityNotFoundException e) {
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error deleting exercise: " + e.getMessage());
        }
    }
//서비스
@Transactional
    public void deleteExerciseSet(Long setId) {
        ExerciseSet exerciseSet = exerciseSetRepository.findById(setId)
                .orElseThrow(() -> new EntityNotFoundException("Exercise not found with id: " + setId));

        exerciseSetRepository.delete(exerciseSet);
    }

 

 

4. 운동종목삭제 api

//컨트롤러
@DeleteMapping("/{exerciseId}")
    public ResponseEntity<?> deleteExercise(@PathVariable Long exerciseId) {
        try {
            exerciseService.deleteExercise(exerciseId);
            return ResponseEntity.ok().build();
        } catch (EntityNotFoundException e) {
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error deleting exercise: " + e.getMessage());
        }
    }
//서비스
@Transactional
    public void deleteExercise(Long exerciseId) {
        Exercise exercise = exerciseRepository.findById(exerciseId)
                .orElseThrow(() -> new EntityNotFoundException("Exercise not found with id: " + exerciseId));

        exerciseRepository.delete(exercise);
    }

'프로젝트 > 운동일지' 카테고리의 다른 글

코드리뷰 - View 부분(HTML,CSS,JavaScript)  (1) 2024.06.11
오류발생 - 총볼륨 구하는 로직  (2) 2024.06.10
프로젝트 개요  (1) 2024.06.04