본문 바로가기
카테고리 없음

<Spring> 일정 관리 앱 만들기 troubleshooting

by 차리하루일기 2024. 10. 4.

api 명세서의 변경 

메서드 url 경로? api 기능 requset requset body  response
POST /schedule 일정 생성 요청 body 할일, 작성자명, 비밀번호, 작성일자  id. 할일, 작성자명, 작성일
GET /schedules 전체 일정 조회 요청 param - id. 할일, 작성자명, 작성일
PUT /schedule/{id} 일정 수정 요청 param 할일 작성자명 비밀번호 {메세지 : 수-정}
DELETE /schedule/{id} 일정 삭제  요청 param 비밀번호  {메세지 : 삭-제}

 

api명세서가 어제와는 다르게 특정 일정 조회 문구를 삭제하였다. 특정 일정 조회를 하였을 때 무언가 문제가 발생할 거 같아서 일단 삭제했다..... 

 

A. requestparam  

A-1) 문제

Spring Boot에서 RequestParam의 개념과 이를 어떻게 활용해야 하는지 잘 이해하지 못했다. 특히, URL에 파라미터를 넣어 서버로 값을 전달하는 방법이 어려웠다. 예를 들어, URL에 특정 필터링 조건이나 쿼리 값을 어떻게 전달하는지 모르겠었다.

 

A-2) 해결

RequestParam은 클라이언트에서 전달되는 쿼리 파라미터를 서버에서 받을 때 사용하는 애너테이션이다. 예를 들어, GET 요청에서 ?key=value 형식으로 데이터를 넘길 수 있으며, 이 값을 컨트롤러에서 받을 수 있다.

@GetMapping("/schedules")
public List<ScheduleResponseDto> getSchedules(
    @RequestParam(required = false) String creator,
    @RequestParam(required = false) String task) {
    return scheduleService.getFilteredSchedules(creator, task);
}

위 코드에서 @RequestParam을 사용하면, 클라이언트는 /schedules?creator=개똥이&task=회의 준비와 같은 요청을 보낼 수 있고, 이를 컨트롤러에서 받아 처리할 수 있다.

 

A-3) 배운 점

RequestParam은 클라이언트가 서버에 데이터를 전달하는 중요한 방법 중 하나이다. 특히, 필터링이나 검색 같은 기능을 구현할 때 좋은것 같다.

 

required=false 옵션을 사용하면 파라미터가 필수는 아니며, 값이 전달되지 않았을 경우 null이 설정된다.

 

B. DB적용

B-1)문제

데이터베이스를 프로젝트에 처음 적용할 때, 데이터베이스와 연결하는 과정SQL 쿼리를 어떻게 사용하는지 어려움이 있었다. 특히, JDBC 템플릿을 사용하여 데이터베이스와 상호작용하는 방법에 대해 많이 고민했다.

 

B-2)해결 

강의를 보고,, 따라 적었다,.,, JDBCTEMPLETE의 경우 코드 스니펫에서 가져와서 APPLICATION.PROPERTIES에 적용하는 것을 따라해 보았고, 
REPOSITORY 클래스 에서 SQL문을 작석 및 실행 해 보았다. 

public Schedule findById(Long id) {
    String sql = "SELECT * FROM schedule WHERE id = ?";
    return jdbcTemplate.queryForObject(sql, new RowMapper<Schedule>() {
        @Override
        public Schedule mapRow(ResultSet rs, int rowNum) throws SQLException {
            Schedule schedule = new Schedule();
            schedule.setId(rs.getLong("id"));
            schedule.setTask(rs.getString("task"));
            schedule.setCreator(rs.getString("creator"));
            schedule.setPassword(rs.getString("password"));
            schedule.setCreatedAt(rs.getTimestamp("created_at").toLocalDateTime());
            schedule.setUpdatedAt(rs.getTimestamp("updated_at").toLocalDateTime());
            return schedule;
        }
    }, id);
}

 

B-3)배운 점

,,

 

C. 3 LAYER 아키텍쳐에서 역할 나누기

C-1) 문제

각 계층의 역할을 나눈다?. 코드를 어떤식으로 분배해야 하나? 라는 고민을 많이 했고 특히, 컨트롤러, 서비스,레파지토리의 역할을 명확히 구분하는 것은 SPRING을 갓 배운 나에게 있어 큰 벽이였다. 

 

C-2) 해결

이 부분도 MEMO 강의를 토대로 따라서 작성하였다. 

CONTROLLER (프리젠테이션) : 클라이언트의 요청을 받아들이고, 응답을 반환하는 부분

SERVICE(비즈니스 로직) : 비즈니스 로직을 처리하고, 레파지토리와 상호작용한다.

REPOSITORY(데이터 접근) : 데이터베이스와 직접 상호작용하여 데이트를 조회하거나 저장하는 역할 

 

각 계층에서 역할 구분 예시:

 CONTROLLER

@GetMapping("/schedules/{id}")
public ScheduleResponseDto getScheduleById(@PathVariable Long id) {
    return scheduleService.getScheduleById(id);
}

 

SERVICE

public ScheduleResponseDto getScheduleById(Long id) {
    Schedule schedule = scheduleRepository.findById(id);
    if (schedule == null) {
        throw new NoSuchElementException("해당 일정이 존재하지 않습니다.");
    }
    return new ScheduleResponseDto(schedule);
}

 

REPOSITROY

public Schedule findById(Long id) {
    String sql = "SELECT * FROM schedule WHERE id = ?";
    return jdbcTemplate.queryForObject(sql, new RowMapper<Schedule>() {
        @Override
        public Schedule mapRow(ResultSet rs, int rowNum) throws SQLException {
            Schedule schedule = new Schedule();
            schedule.setId(rs.getLong("id"));
            schedule.setTask(rs.getString("task"));
            schedule.setCreator(rs.getString("creator"));
            schedule.setPassword(rs.getString("password"));
            schedule.setCreatedAt(rs.getTimestamp("created_at").toLocalDateTime());
            schedule.setUpdatedAt(rs.getTimestamp("updated_at").toLocalDateTime());
            return schedule;
        }
    }, id);
}

 

C-3)배운 점

,,, 강의를 보고 따라한 수준이라 잘 모르겠다..

일단 구조가 효율적으로 작성된 점이 유지보수에 편해 보인다.