책 스프링부트와 AWS로 혼자 구현하는 웹서비스
따라하기
어제 update 가 작동되는 것 까지 확인 했으니 오늘은
로컬환경에선 데이터베이스로 H2를 사용합니다. 메모리에서 실행하기 때문에
직접 접근하려면 웹 콘솔
을 사용해야만 합니다.
application.properties
에 옵션을 추가해주자spring.h2.console.enabled=true
등록한 뒤에 Application
의 main 메서드를 실행해주자.
톰캣이 실행된다면 정상적으로 작동한 거다.
localhost:8080/h2-console
로 접속해보자이렇게 나오면 성공
JDBC URL 의 주소가 책이랑 좀 다르니 책처럼 고쳐주자
jdbc:h2:mem:testdb
라고 수정해주자
Connect 를 눌러보자
POSTS 테이블이 정상적으로 나온다.
SELECT * FROM posts;
아직 데이터가 없어서 아무것도 나오지 않는다.
insert 로 데이터를 하나 넣어주자.
INSERT INTO posts (author, content, title) VALUES ('author1', 'content1', 'title1');
localhost:8080
뒤에 우리가 만들어준 주소인 /api/v1/posts/{id}
를 넣어보자. id 대신 1을 넣어야겠지?방금 insert 해줬던 내용이 잘 나온다.
저자는 Chrome 에 JSON Viewer라는 플러그인을 설치했습니다. 정렬된 JSON형태가 보고싶으신 분들은 해당 플러그인을 설치해보세요.
나오긴 나오는데 책이랑 형태가 좀 다르게 나오길래 또 심장 떨어질 뻔했는데, 저자는 정말 모르는 게 없다. 내 마음 다 알아준다.
언제 만들어졌는지, 수정되었는지 등은 차후 유지보수에 있어 굉장히 중요한 정보입ㄴ디ㅏ. 그렇다보니 DB에 매번 insert, update 전 날짜 데이터를 등록, 수정하는 코드가 여기저기 들어가게 되는데 이런 반복적인 코드가 모든 테이블과 서비스 메서드에 포함되어야 한다고 생각하면 ... 그래서 이 문제를 해결하고자
JPA Auditing
을 사용하겠습니다.
Java 8 부터 LocalDate 와 LocalDateTime 이 등장했는데, 기존의 Date의 문제점을 완전히 고친 타입이라 Java8 이라면 무조건 써야합니다. LocalDate 와 LocalDateTime 이 데이터베이스에 제대로 매핑되지 않는 이슈가 Hibernate 5.2.10 버전에서 해결되었기 때문에 우리는 이제 걱정할 것이 없습니다.
좋습니다. 전혀 걱정되지 않습니다. 시작합니다.
BaseTimeEntity.java
클래스를 만들어줍니다.// BaseTimeEntity.java
package com.prac.webservice.springboot.domain;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseTimeEntity {
@CreatedDate
private LocalDateTime createDate;
@LastModifiedDate
private LocalDateTime modifiedDate;
}
BaseTimeEntity 클래스는 모든 Entity 의 상위 클래스가 되어 Entity 들의 createdDate, modifiedDate 를 자동으로 관리하는 역할입니다.
@MappedSuperClass
: JPA Entity 클래스들이 BaseTimeEntity 를 상속할 경우 필드들도 칼럼으로 인식하게 합니다.
@EntityListeners(AuditingEntityListener.class)
: BaseTimeEntity 클래스에 Auditing 기능을 포함시킵니다.
Auditing 기능이 뭐죠?
@CreatedDate
: Entity 가 생성되어 저장될 때 시간이 자동 저장됩니다.
@LastModifiedDate
: 조회한 Entity의 값을 변경할 때 시간이 자동 저장됩니다.
Posts
클래스가 BaseTimeEntity
를 상속받도록 변경합니다.클래스 이름 뒤쪽에 extends BaseTimeEntity
를 추가해준다.
Application
클래스에 활성화 어노테이션을 하나 추가한다.@EnableJpaAuditing
JPA Auditing 어노테이션들을 모두 활성화 할 수 있게 해주는 것.
PostsRepositoryTest.java
에 코드를 추가한다.// PostsRepositoryTest.java
@Test
public void BaseTimeEntity_등록 () {
// given
LocalDateTime now = LocalDateTime.of(2022,6,29,2,11,0);
postsRepository.save(Posts.builder()
.title("title")
.content("content")
.author("author")
.build());
// when
List<Posts> postsList = postsRepository.findAll();
// then
Posts posts = postsList.get(0);
System.out.println(">>>> CreateDate = " + posts.getCreateDate() + ", modifiedDate = " + posts.getModifiedDate());
assertThat(posts.getCreateDate()).isAfter(now);
assertThat(posts.getModifiedDate()).isAfter(now);
}
내가 적은 시간과 상관 없이
테스트 시간이 들어간 거 같다. 실제 시간이 잘 들어 간 거니 오히려 좋은 거 겠지.
근데 그럼 내가 적어 넣은 now 라는 시간은 뭐하는 걸까?
JPA 에 대해 좀 더 자세하게 공부하고 싶으신 분들은
김영한
님의자바 ORM 표준 JPA 프로그래밍(에이콘)
을 참고해보세요.
넵! 감사합니다! 꼭 읽어보겠습니다!
내일은 템플릿 엔진을 이용해 화면을 만들어본답니다!
뭔가 제대로 되는지 안되는지도 모르고 따라쓰고 있는 듯한 기분이 드는 건 졸린 탓이겠지.