어제에 이어 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 |