일정 작성 프로그램에 작성일과 수정일 적용(Timestamped) 스프링 과제 복기

이상민·2024년 8월 25일
0

이번주에 스프링 프로젝트를 시작할때 초기 틀을 만드는 법과 3Layer Architecture를 활용하는 법을 강의로 듣고 저번주에 작업했던 일정 작성 프로그램 과제를 다시 만들어 보기로 하였다.

1단계: 일정 작성

  • 조건
    1. 일정에 할일, 담당자명, 비밀번호, 작성/수정일 정보를 저장할 수 있어야 함.
    2. 각 일정의 고유 식별자(ID)가 자동으로 생성됨.
    3. 최초 작성 시 작성일수정일은 동일함.

패키지 나누기

먼저 entity, dto, controller, service, repository 이렇게 5개의 패키지를 만들고, 필요한 클래스들을 만들어 주었다.

Timestamped?

타임스탬프를 활용하면서 처음보는 어노테이션들이 많았는데,

@MappedSuperclass:
이 클래스를 엔티티의 부모 클래스처럼 사용할 수 있게 해줌

@EntityListeners(AuditingEntityListener.class):
엔티티가 생성되거나 수정될 때 자동으로 그 시점의 시간을 기록해주는 JPA 감시 기능(Auditing)을 활성화하는 어노테이션

@CreatedDate :

엔티티가 처음 생성될 때, 즉 처음 저장될 때 생성 시점이 자동으로 createdAt 필드에 기록

@LastModifiedDate :

엔티티가 수정될 때마다 자동으로 수정 시점이 modifiedAt 필드에 기록

@Column(updatable = false) :

이 어노테이션은 해당 필드가 DB에 삽입된 후에는 수정되지 않도록 설정. 즉, createdAt 필드는 처음 생성된 이후 변경되지 않음

@Temporal(TemporalType.TIMESTAMP) :

날짜와 시간을 DB에 저장할 때의 타입을 지정. TemporalType.TIMESTAMP는 날짜와 시간을 모두 저장하는 형식

Timestamped 클래스를 요약하면

= 엔티티의 생성 및 수정 시간을 자동으로 관리하기 위한 추상 클래스이다.

Todo entity

Timestamped 클래스를 상속받고 있다

@GeneratedValue(strategy = GenerationType.IDENTITY) 를 이용하여 Auto increament 기능 활용

@EnableJpaAuditing?

스프링 애플리케이션에서 엔티티의 생성 및 수정 시간을 자동으로 관리하고 기록할 수 있게 해주는 JPA Auditing 기능을 활성화하는 어노테이션

나는 @CreatedDate, @LastModifiedDate 와 같은 Timestamped클래스에 있는 어노테이션이 자동으로 동작하는 기능을 활성화 시켜주기 위해서 활용

1단계: 일정 작성

  • controller

  • service

  • dto

생성일과 변경일의 날짜와 시간을 표현하기 위해 LocalDateTime 사용

2단계: 선택한 일정 조회

  • controller

Id를 받기위해서 @pathvariable방식을 활용

  • service

아이디를 먼저 조회한 후 만약 null값이 있다면 예외처리를 해준다.

  • dto

3단계: 일정 목록 조회

  • 조건

    1. 수정일(형식: YYYY-MM-DD) 및 담당자명을 기준으로 일정 목록을 조회할 수 있음.
      • YYYY-MM-DD를 LocalDateTime으로 변환
                // YYYY-MM-DD 형식의 문자열
                String startDateStr = "2024-08-01";
                String endDateStr = "2024-08-31";
        
                // LocalDate를 LocalDateTime으로 변환
                LocalDateTime startDateTime = LocalDate.parse(startDateStr).atStartOfDay();
                LocalDateTime endDateTime = LocalDate.parse(endDateStr).atTime(LocalTime.MAX);
    2. 조건을 둘 다, 한 가지, 또는 아무것도 충족하지 않아도 조회가 가능함.
    3. 수정일 기준 내림차순으로 정렬하여 조회함.
  • controller

  • service

해석 :

LocalDateTime startDateTime = LocalDate.parse(date).atStartOfDay();:

date라는 문자열을 LocalDate로 변환한 후, 해당 날짜의 시작 시간을 구함
atStartOfDay() 메서드는 그 날짜의 자정(00:00:00) 시간을 의미하는 LocalDateTime 객체를 반환.
예를 들어, date가 "2024-08-26"이라면, startDateTime은 "2024-08-26T00:00:00"이 된다.

LocalDateTime endDateTime = LocalDate.parse(date).atTime(LocalTime.MAX);:

이 코드는 주어진 날짜의 끝 시간을 설정하는 부분.
LocalTime.MAX는 하루의 마지막 순간인 23:59:59.999999999을 나타낸다. 따라서 date가 "2024-08-26"이라면, endDateTime은 "2024-08-26T23:59:59.999999999"이 된다.

List<Todo> todos = todoRepository.findAllByIdCreatedAtBetweenOrderByModifiedAtDesc(startDateTime, endDateTime);:

todoRepository를 통해 데이터베이스에서 할 일 목록을 조회.
findAllByIdCreatedAtBetweenOrderByModifiedAtDesc 메서드는 다음과 같은 역할:
CreatedAtstartDateTimeendDateTime 사이에 있는 모든 할 일 항목을 조회. 즉, 주어진 날짜에 생성된 할 일들을 조회.
OrderByModifiedAtDesc는 조회된 결과를 modifiedAt(마지막 수정 시간)을 기준으로 내림차순으로 정렬. 즉, 가장 최근에 수정된 항목이 먼저 나오게 됨

따라서 :

이 코드는 특정 날짜의 자정부터 그날의 마지막 순간까지 생성된 할 일 목록을 조회하고, 이를 마지막 수정 시간이 가장 최근인 항목부터 내림차순으로 정렬해 가져오는 작업을 수행하는 코드이다.

  • dto

4단계: 선택한 일정 수정

  • 조건

    1. 일정의 할일, 담당자명만 수정 가능.
    2. 수정 시 비밀번호를 함께 전달함.
    3. 작성일은 변경되지 않으며, 수정일은 현재 시점으로 변경됨.
    4. 수정된 일정의 정보를 반환하여 확인할 수 있어야 함.
  • controller

아이디를 통해 조회하고 사용자의 변경사항을 입력받아야 하기 때문에 @RequestBody 활용

  • service

update 메서드를 활용하기 위해서

Todo 엔티티에 만들어 준다.

  • dto

조건에서 할일, 담당자명 만 수정 가능하므로 두개만 ResponseDto에 넣어서 반환해준다.

5단계: 선택한 일정 삭제

  • 조건
    1. 고유 식별자(ID)를 사용해 선택한 일정을 삭제할 수 있음.
    2. 삭제 요청 시 비밀번호를 함께 전달함.
  • controller

사용자의 비밀번호 입력을 받아야 하므로 @RequestBody 활용

따라서 deleteDto

  • service

passwordnull인 경우와 동일하지 않는 경우에 각각 예외처리를 해준 후, Id를 조회하여 레포지토리에서 삭제시킨다.

git hub
https://github.com/Sangmin1999/timestamped/commits/main/

마무리

이렇게 강의를 통해 배운 내용을 가지고 저번에 미숙했던 스프링 과제를 다시 만들어 보았다. 확실히 처음보다 기본 틀을 잡는 부분이 많이 발전한 느낌을 받았다. 그리고 Timestamped를 활용하여 처음으로 생성일과 변경일을 만들어 보았는데, 쿼리문과 추상클래스를 만들때 스스로가 많이 어색했다. 그래도 이번에 시간에 관한 프로그래밍을 활용하는 방법을 얻는 시간이 되어서 발전하는 기분이 많이 들었던 시간이였다.

profile
안녕하세요

0개의 댓글