ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] 과제 - 일정관리 앱 만들기LV1~2
    Spring 2025. 3. 26. 13:25
    minecraft-font

     

    과제

     생성, 조회

    목표

        일정 관리 앱을 만듦으로서 API 작성의 이해, Layerd 구조 이해, SQL 데이터 관리 등을 이해한다.

         FORNT 작업은 없고, JDBC 구조로 되어 있는 로직에 데이터 결과를 출력해본다.

         (POSTMAN으로 테스트 하기)

     

         이전에는 API, ERD, SQL작업 했다면 지금은 기본적으로 생성, 조회, 수정 , 삭제로직을 만들 것이다.

            

     

    API, ERD, SQL 리뉴얼

     

    https://note8770.tistory.com/78

     

    [Spring] 과제 - 일정관리 앱 만들기LV0

    과제 목표 API 작성 ERD 작성 SQL 작성 목표    일정 관리 앱을 만듦으로서 API 작성의 이해, Layerd 구조 이해, SQL 데이터 관리 등을 이해한다.     FORNT 작업은 없고, JDBC로 직접 데이터를 넣어 결과

    note8770.tistory.com

    과제를 진행 하면서 API가 수정이 완료 되었다.

    수정이유는 명칭 규약을 지켜야한다. 변수명은 카넬케이스, 데이터베이스는 스네이크케이스로 좀더 직관적으로 수정했다.

     

    생성, 조회

    REPOSITORY

     public ScheduleResponseDto saveSchedule(Schedule schedule) {
            SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
            jdbcInsert.withTableName("schedule_data").usingGeneratedKeyColumns("id");
    
            Map<String, Object> parameters = new HashMap<>();
            parameters.put("user_pw", schedule.getUserPw());
            parameters.put("name", schedule.getName());
            parameters.put("todo", schedule.getTodo());
            parameters.put("created_at", LocalDateTime.now());
            parameters.put("updated_at", LocalDateTime.now());
    
            // 저장 후 생성된 key값을 Number 타입으로 반환하는 메서드
            Number key = jdbcInsert.executeAndReturnKey(new MapSqlParameterSource(parameters));
    
            return new ScheduleResponseDto(key.longValue(), schedule.getUserPw(), schedule.getName(), schedule.getTodo(),schedule.getCreated_at(), schedule.getUpdated_at());
        }
    
    
        public List<ScheduleResponseDto> findAllSchedule(String day, String name) {
            if(day!= null && name == null) {
                return jdbcTemplate.query("SELECT * FROM schedule_data WHERE substring(updated_at, 1,7) like? ORDER BY updated_at DESC", scheduleRowMapper(), day);
            }else if (name != null && day==null) {
                return jdbcTemplate.query("SELECT * FROM schedule_data WHERE  name =? ORDER BY updated_at DESC", scheduleRowMapper(), name);
            }else {
                return jdbcTemplate.query("SELECT * FROM schedule_data ORDER BY updated_at DESC", scheduleRowMapper());
            }
        }
        private RowMapper<ScheduleResponseDto> scheduleRowMapper(){
            return new RowMapper<ScheduleResponseDto>() {
                @Override
                public ScheduleResponseDto mapRow(ResultSet rs, int rowNum) throws SQLException {
                    return new ScheduleResponseDto(
                            rs.getLong("id"),
                            rs.getString("user_pw"),
                            rs.getString("name"),
                            rs.getString("todo"),
                            rs.getString("created_at"),
                            rs.getString("updated_at")
                    );
                }
            };
        }

     

    포스트맨에서 데이터가 추가 되었을때, saveSchedule 메소드, 전체 조회 메소드 이다.

    saveSchedule에서는 다음 SQL 처럼 구성했을때

    #MySQL 데이터 생성
     CREATE TABLE schedule_data(
           id BIGINT AUTO_INCREMENT primary key comment 'id',
           user_pw VARCHAR(20) comment 'UserPW',
           name VARCHAR(20) comment  'name',
           todo VARCHAR(100) comment 'Todo',
           created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
           updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP on UPDATE CURRENT_TIMESTAMP
    );

    데이터를 추가 되었을때 구글링을 해서 DEFAULT CURRENT_TIMESTAMP를 사용하면 된다고 했다. 값이 없다면 현재시간을 저장하는 것으로 UPDATE CURRENT_TIMESTAMP를 적용하면 자동으로되는 줄 알았으나 구글링한 방법을 가능한 만큼 시험해봤지만 실패했다.

     

    튜터님 말씀으로는 요청 받을때, null이 들어와서 발생하는 문제인것 같은데, 컴퓨터 업로드 시간을 받는거와 같기 때문에 LcoalDataTime.now()로 컴퓨터에 넣어주는 것으로 해결했다.

     

    findAllSchedule메소드의 day와 name은 null을 받을 수 있도록 Contoller에

     @RequestParam을 사용했다. required = false이면 null이 들어와도 동작이 가능하다.

        @GetMapping
        public ResponseEntity<List<ScheduleResponseDto>> findAllSchedule(@RequestParam(required = false) String day, @RequestParam(required = false) String name ){
    
            return new ResponseEntity<List<ScheduleResponseDto>>(scheduleService.findAllSchedule(day, name), HttpStatus.OK);
        }

     

    포스트맨 입력 방법

    //포스트맨
    //1. ~/schedules?day=2025-03              //2025-03인데이터 조회
    //2. ~/schedules?name=tester              //이름만 조회
    //3. ~/schedules?day=2025-03&name=tester  //두개의 조건 모두 조회 주의 공백도 포함되기 때문에 공백을 미포함되도록 작성할것
    //4. ~/schedules                          // 전체 조회

    findAllSchedule메소드에서는 day와 null인지에 따라 개별 SQL문을 조회 하도록 작성했다.

     

    ※ SQL을 동적으로 변경 가능하게 할수는 있을 것 같은데, 로직이 꼬여서 페스했다.

         WHERE절에 1=1(무조건 참) AND~ 조건, OR 조건 동작할 것같은데...시도는 해봤지만 미숙해서 패스했지만 괜찮은 방법이라 나중에 필요한면 다시 시도하면 좋을것 같다.

     

     참고로 return jdbcTemplate.query(SQL 문, scheduleRowMapper(), Object 요소);   jdbcTemplate.query에는 검색 조건을 Object로 받는다. List<Object>로 day 와 name을 추가하고 List<Object>.toArray로 한다면 요소가 있든, 없든 동작이 가능하다.

     

    substring(updated_at, 1,7) like? 는 월 단위로 조회할 목적인데, 뒤의 일과 겹칠수 있을 것 같아 YEAR-MONTH를 포함하는 형태로 입력을 받아오기로 했다.

        

     

     

    수정,삭제

    내용 수정 Update메소드는 크게 할일(todo) , 작성자(name)의 조건을 가지고 수정 하기 위해, 외부에서 id와 ReuestBody를 받도록  update문으로 SQL문을 구성했다.

     

    updateSchedule을 지금보니 name도 받고있는데 원래라면은 내용만 수정하게 변경하도록 로직을 구성해야하지만, 수정되지 않는걸 뒤늦게 발견했다. 

     

    updateName전체 조회를 하듯 if문으로 하면 개별 수정 조건을하면 두개의 Update 조건을 하나로 만들수 있을 것 같다. 

     

    또한, 내용을 업데이트 하게 된다면.

     

    2번데이터 조회
    2번 데이터 수정 후

     

    포스트맨에서 조회되었던 데이터와 수정 후 데이터의 update_at이 자동으로 변경되된다.

     

     

    삭제 delete는 pathVarialbe 값으로 id만 선태해서 받는것으로 Where조건문에 id 이전에 userPw값을 먼저 확인하고 실행 하도록 했다.

     

    id는 기본적으로 데이터가 추가되도록 'AUTO_INCREMENT'로 되어 있어 null이 되어 있지 않을것이고, userPw로 추가 적으로 확인 후에 선택한 id를 삭제 전에 정말로 삭제 할건지 여부를 물어보는 용도로 사용 했다. 

     

    회고록

     

    곳곳에 명칭규약을 잊지 않을려고 노력도 하지만, 작업하다보니 대부분 오류가 변수명이나 데이터 명이 틀려서 안되는 경우가 많았다.

     

    설계에대해 중요성을 깊게 깨닭게 되었다. 

     

    'Spring' 카테고리의 다른 글

    [Spring] DNS (Domain Name System)  (0) 2025.03.27
    [Spring] TCP / UDP  (0) 2025.03.27
    [Spring] 과제 - 일정관리 앱 만들기LV0  (0) 2025.03.24
    [Spring] IP(Internet Protocol)  (0) 2025.03.20
    [Spring] 네트워크  (0) 2025.03.20
Designed by Tistory.