본문 바로가기

개발일지(일간)

23년 02월 02일

어제에 이어 jpa에 대해서 배웠다.

오늘은 QueryDSL,Auditing,HateOAS등에 대해서 배웠다.

그리고 어제 깜빡하고 기록하지 못한것이 있는데, 일대 다 연관관계를 맺을 때 리스트를 사용하지 말고, 다음처럼

@OneToMany(mappedBy = "thread", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Comment> comments = new LinkedHashSet<>();

링크드해쉬셋을 사용해주는것이 좋다고 한다.

 

QueryDSL은 문자가 아닌 코드로 쿼리를 작성함으로써, 컴파일 시점에 문법 오류를 쉽게 확인할 수 있다고 한다.

QueryDSL은 QuerydslPredicateExecutor을 레파지토리에 상속시켜 사용할 수 있으며, 조인이 필요한 경우 사용이 불가능 하다.대신, join이 없는 대신 조건이 많은 쿼리는 사용을 고려해볼 만 하다.

 

HATEOAS는 Hypermedia As The Engine of Application State 의 약자이다.

다음 요청을 위한 하이퍼링크가 제공되어야 한다는 뜻이다.

예를 들면 다음과 같다

{
  "data": {
    "id": 1000,
    "name": "게시글 1",
    "content": "HAL JSON을 이용한 예시 JSON",
    "self": "<http://localhost:8080/api/post/1000>", // 호출한 api 주소
    "profile": "<http://localhost:8080/docs#query-article>", // 호출한 api 문서
    "next": "<http://localhost:8080/api/post/1001>", // 다음 post를 조회 api 주소
    "comment": "<http://localhost:8080/api/post/comment>", // post의 댓글 달기 api 주소
    "save": "<http://localhost:8080/api/feed/post/1000>", // post을 내 피드로 저장 api 주소
  },
}

 

Auditing은 엔티티를 누가 언제 생성/마지막 수정 했는지 자동으로 기록되게 할 수 있다.

@EnableJpaAuditing과 @EntityListeners(AuditingEntityListener.class)를 통해 사용할 수 있으며, 직접 구현해서도 사용할 수 있다.

과제로 ContextHolder + 엔티티 라이프 사이클 이벤트(@PrePersist, @PreUpdate) 를사용해서 createdBy, modifiedBy 를 구현해보았다.

profile.java

public class Profile extends TimeStamped {
  ... 생략
  //라이프 사이클 메소드
  @PrePersist
  public void prePersist() {
    super.updateModifiedBy();
    super.updateCreatedBy();
  }

  @PreUpdate
  public void PreUpdate() {
    super.updateModifiedBy();
  }
}

 

TimeStamped.java

public class TimeStamped {

  @CreatedDate
  private LocalDateTime createdAt;
  @LastModifiedDate
  private LocalDateTime modifiedAt;
  @CreatedBy
  @ManyToOne
  private User createdBy;
  @LastModifiedBy
  @ManyToOne
  private User modifiedBy;

  public void updateCreatedBy() {
    var user = getCurrentAuditor();
    user.ifPresent(value -> this.createdBy = value);
  }

  public void updateModifiedBy() {
    var user = getCurrentAuditor();
    user.ifPresent(value -> this.modifiedBy = value);
  }

  private Optional<User> getCurrentAuditor() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

    if (authentication == null || !authentication.isAuthenticated()) {
      return Optional.empty();
    }

    return Optional.of(((UserDetailsImpl) authentication.getPrincipal()).getUser());
  }
}

ContextHolder를 이용해야 하기에 TimeStamped클래스 안에 getCurrentAuditor()란 메서드를 생성해 컨텍스트에서 User를 가져오도록 했는데 이게 맞는지는 잘 모르겠다.

'개발일지(일간)' 카테고리의 다른 글

23년 02월 06일  (0) 2023.02.07
23년 02월 03일  (0) 2023.02.05
23년 02월 01일  (0) 2023.02.02
23년 01월 31일  (0) 2023.02.01
23년 1월 30일  (0) 2023.01.30