일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 파이썬3
- 디자인 패턴
- java
- 안드로이드
- 장고
- bytecode
- Spring Boot
- mysql
- JPA
- Python
- HTTP
- python3
- 파이썬
- db
- 데이터베이스
- 스프링부트
- 스프링
- ORM
- 자바
- 스프링 부트
- 웹 개발
- rabbitmq
- 자료구조
- 개발
- django
- 보안
- BCI
- 웹
- Spring
- node.js
- Today
- Total
semtax의 개발 일지
스프링부트로 게시판 만들기 7 : 데이터 Auditing 본문
개요
이번 포스팅에서는 Data Auditing(데이터 이력 관리) 에 대해서 다루어 보도록 하겠다.
Data Auditing?
상황을 1가지 가정해보자, 만약 당신이 게시판 관리자고, 관리자 페이지를 통해서 게시글 댓글목록을 관리 하고 있다고 가정을 해보자.
그렇다면 언제 이 글이나 댓글을 작성했는지 라던가, 누가 작성했는지를 알아야, 나중에 차단을 시키던지 다른걸 하던지 관리를 할 수가 있다.
또한, 사용자에 따라서 글 쓰는 기능을 제한 하는 기능도 위의 Data Auditing이 있어야 가능하다.
바로 위와 같은 이유들 때문에, 이러한 데이터 이력관리가 중요하다는 것을 알 수 있다.
하지만 이러한 데이터 이력관리를 처음부터 만들기에는 뭔가 귀찮다. 뭔가 누가 만들어 놓은게 있을것같다.
다행히도, JPA에서는 이러한 기능을 이미 제공해주고 있다.
이제, 어떻게 사용하는지 알아보도록 하겠다.
구현
먼저 Auditing 정보를 저장하는 Entitiy를 생성해주자.
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
public class BaseEntity {
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdTime;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
@CreatedBy
@Column(updatable = false)
private String createdBy;
@LastModifiedBy
private String lastModifiedBy;
public LocalDateTime getCreatedTime() {
return createdTime;
}
public LocalDateTime getLastModifiedDate() {
return lastModifiedDate;
}
public String getCreatedBy() {
return createdBy;
}
public String getLastModifiedBy() {
return lastModifiedBy;
}
}
위에서, @EntityListeners를 통해서 엔티티의 영속성 컨텍스트 라이프 사이클에 따른 Auditing 정보를 세팅하는 콜백함수를 등록 한다.
그리고, @CreateBy, @ModifiedBy, @CreateByDate, @ModifiedByDate 어노테이션을 통해서 Auditing 정보를 추가 해주는걸 알 수 있다.
이때, @CreateBy, @ModifiedBy를 붙여준 필드 같은 경우에는, 스프링에서 "AuditorAware
마지막으로, @MappedSuperclass 를 이용해서 다른 Entity에서 선언한 Auditing Entity를 상속을 통해 포함할 수 있게 해준다.
이렇게 하면 엔티티의 영속성 컨텍스트 라이프 사이클에 맞춰서 Auditing 정보가 등록되게 된다.
이제 게시글 Entitiy에 아까전에 만들어준 객체를 아래와 같이 상속받으면 된다.
@Entity
public class Post extends BaseEntity{
@Id @GeneratedValue
@Column(name = "post_id")
private Long Id;
private String title;
private String content;
public Long getId() {
return Id;
}
public void setId(Long id) {
Id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Post post = (Post) o;
return Objects.equals(Id, post.Id) &&
Objects.equals(title, post.title) &&
Objects.equals(content, post.content);
}
@Override
public int hashCode() {
return Objects.hash(Id, title, content);
}
}
댓글 Entity도 아래와 같이 추가해준다.
@Entity
public class Comment extends BaseEntity{
@Id @GeneratedValue
@Column(name = "comment_id")
private Long Id;
private String title;
private String content;
@ManyToOne
@JoinColumn(name = "post_id")
private Post post;
public Long getId() {
return Id;
}
public void setId(Long id) {
Id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Post getPost() {
return post;
}
public void setPost(Post post) {
this.post = post;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Comment comment = (Comment) o;
return Objects.equals(Id, comment.Id) &&
Objects.equals(title, comment.title) &&
Objects.equals(content, comment.content);
}
@Override
public int hashCode() {
return Objects.hash(Id, title, content);
}
}
다음으로, 아래 코드처럼 어노테이션을 이용해서 JPA Auditing 기능을 활성화 하겠다고 설정한다.
@EnableJpaAuditing
@SpringBootApplication
public class SemtaxApplication {
public static void main(String[] args) {
SpringApplication.run(SemtaxApplication.class, args);
}
@Bean
public AuditorAware<String> auditorProvider() {
return () -> {
ServletRequestAttributes attr
= (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
String currentUser = (String)attr.getRequest().getSession().getAttribute(Sessions.SESSION_ID);
if(currentUser != null)
return Optional.of(currentUser);
else
return Optional.of("Anonymous");
};
};
}
위 코드에서, RequestContextHolder 라는 클래스를 사용했는데, 이를 이용해서 Servlet 요청 객체를 가져올수 있다. 이걸 이용해서 서블릿 요청 내에 있는 session 값을 가져 올 수 있다.
(스프링 시큐리티를 쓰는 경우에는 SecurityContext를 통해 세션 정보들을 가져와서 넣어주면 된다.)
테스트
Postman을 켜서 아래와 같이 테스트를 해보자
추가한 Auditing 정보들(글쓴이, 수정한이, 수정날짜, 생성날짜)이 정상적으로 표시되는것을 알 수 있다.
'개발 > Java' 카테고리의 다른 글
스프링부트로 게시판 만들기 9 : 페이징 기능 구현 (2) | 2020.05.01 |
---|---|
스프링부트로 게시판 만들기 8 : 권한 체크 (0) | 2020.05.01 |
스프링부트로 게시판 만들기 6 : 로그인 기능 추가 (4) | 2020.05.01 |
스프링부트로 게시판 만들기 5 : 회원가입 기능 추가 (0) | 2020.05.01 |
스프링부트로 게시판 만들기 4 : JPA 매핑 기능을 이용해 댓글 기능 추가하기 (0) | 2020.02.26 |