TIL - 0523
스프링부트
게시글 상태 구현하기
- 게시글 바로 삭제가 아닌 상태만 변경하기
- 복구 요청, 보관 개념으로 상태만 변경해두었다가 일정 기간이 지났을 때 데이터베이스에서 삭제하도록 만들기
- deleted 상태 : true / false로 구분
- Question 엔티티 boolean을 저장하는 방법으로 해결
/* Entity */
@Entity
public class Qusetion {
.
.
.
@Column(nullable = false)
private boolean deleted;
}
- Question 엔티티 boolean 대신 문자 혹은 0, 1로 저장하는 방법으로 해결
- 방법1 : JPA 기능 중 컨버터 기능을 사용하면 됨 - javax.persistence.AttributeConverter, import javax.persistence.Converter
- 방법2 : @Type(type = “org.hibernate.type.NumericBooleanType”) 사용하기
/* Entity */
@Entity
public class Qusetion {
.
.
.
@Convert(converter = BooleanToYNConverter)
@Column(nullable = false)
private boolean deleted;
}
/* Entity Attribute Converter */
@Converter
public class BooleanToYNConverter implements AttributeConverter<Boolean, String> {
@Override
public String convertToDatabaseColumn(Boolean attribute) {
return (attribute != null && attribute) ? "Y" : "N";
}
@Override
public Boolean convertToEntityAttribute(String s) {
return "Y".equals(s);
}
}
- 삭제 상태의 Question은 출력되지않도록 꺼내올 때 사용할 엔티티 쿼리메소드 정의하기
- 컨벤션 : spring jpa query methods docs
- 컨벤션에 맞춰서 메소드만 정의해두면 구현하지않더라도 JPA가 알아서 코드 완성 : 해당 메소드 실행하면 쿼리 실행
public interface QuestionRepository extends JpaRepository<Question, Long> {
List<Question> findByDeletedIsFalse();
}
- 게시글에 달린 댓글 중 삭제상태가 아닌 댓글만 찾아오기 : 조회할 때 댓글(조인컬럼)까지 가져옴
- List<>로 반환받음 : stream 적용
- 도메인 객체에 판단을 맡겨라 : 요청 메세지를 보내서 처리하도록 해야지, 꺼내서 처리하면 안됨(answer가 삭제되었는지는 answer가 알지 상태값을 가져와서 판단하면 안됨)
/* QuestionController.java */
@GetMapping("/{id}")
public String show(@PathVariable Long id, Model model) {
.
.
.
model.addAttribute("question", questionRepo.findById(id).get());
}
/* Question.java (Entity) */
@Entity
public class Question {
.
.
.
@OneToMany(mappedBy = "question")
@OrderBy("id ASC")
private List<Answer> answers;
.
.
.
public List<Answer> getValidAnswers() {
return answers.filter(answer -> !answer.isDeleted()).collect(toList());
}
}
/* /questions/show */
<article class="article" id="answer-1405">
<div class="article-header">
<div class="article-header-thumb">
<img src="https://graph.facebook.com/v2.3/1324855987/picture" class="article-author-thumb" alt="">
</div>
<div class="article-header-text">
<a href="/users/" class="article-author-name"></a>
<a href="#answer-1434" class="article-header-time" title="퍼머링크"></a>
</div>
</div>
<div class="article-doc comment-doc">
<p></p>
</div>
<div class="article-util">
<ul class="article-util-list">
<li><a class="link-modify-article" href="/questions//answers//edit">수정</a></li>
<li>
<form class="delete-answer-form" action="/questions//answers/" method="POST">
<input type="hidden" name="_method" value="DELETE">
<button type="submit" class="delete-answer-button">삭제</button>
</form>
</li>
</ul>
</div>
</div>
</article>