비공개 상태비공개 상태비공개 → 공개로 전환 (전환 후에는 목록 조회를 통해서도 조회됨)나의 생각
1. 등록할 때는 기본적으로isPrivate = true여야겠다.
2.@patch로isPrivate = true->isPrivate = false로 변경
3.isPrivate = false는 setIsPrivate함수를 만들어서 사용하면 개발자 다른 분이 봐도 바뀐다고 인식할 것 같다.
Lecture Entity에 private boolean isPrivate = true;을 추가해주고, 공개용 함수를 만든다.
public void setPublic(){
this.isPrivate = false;
}
@PatchMapping("/lectures/{lectureId}")
public void updatePrivate(@PathVariable Long lectureId){
lectureService.updatePrivate(lectureId);
}
patch는 하나만, 한 부분만 수정하고 싶을 때 주로 사용한다.
@Transactional
public void updatePrivate(Long lectureId) {
Lecture lecture = lectureRepository.findById(lectureId)
.orElseThrow(() -> new NoSuchElementException("찾는 강의가 없습니다."));
lecture.setPublic();
lectureRepository.save(lecture);
}
@Transactionalvssave()
현재 이 코드에서는 2가지가 같은 기능을 한다. 따라서 둘 중 하나만 있으면 된다. 두가지 중 어떤게 더 효과적인가?그럼 어떻게 동작하는지 보자
- @Transactional
@Transactional이 붙어 있어 트랜잭션이 시작됨.- lectureRepository.findById()를 통해 엔티티를 가져옴 → 영속성 컨텍스트(Persistence Context)에 저장됨.
- lecture.setPublic();을 호출하면 영속 상태 엔티티의 필드 값이 변경됨.
- 트랜잭션이 끝나는 시점에서 JPA의 변경 감지(dirty checking)가 동작해서 자동으로 UPDATE SQL 실행됨.
: 즉, save() 없이도 변경 사항이 DB에 반영됨.
- save()
lectureRepository.findById()로 엔티티를 가져옴.lecture.setPublic();을 통해 필드 값을 변경함.lectureRepository.save(lecture);를 호출하면 JPA가 변경된 내용을 DB에 반영하기 위해 명시적인 UPDATE 쿼리를 실행함.
📌
@Transactional: JPA의 변경 감지(dirty checking)를 활용하면 성능적으로 더 효율적
save()는 새로운 엔티티를 저장하거나, 비영속 상태의 엔티티를 업데이트할 때만 사용하는 것이 좋음.❓그럼 언제 save()를 써야 할까?
객체가 영속성 컨텍스트에 없는 상태일 경우(비영속 상태)
Spring Data JPA의 @Transactional(readOnly = true)로 인해 변경 감지가 비활성화된 경우
따라서 나는 save말고, Transactional을 사용하겠다!
나는 QueryDsl로 사용하려고 한다.
public List<Lecture> findAll(){
return jpaQueryFactory
.selectFrom(lecture)
.join(lecture.teacher).fetchJoin()
.where(
lecture.deleted.isFalse(),
lecture.isPrivate.isFalse())
.orderBy(lecture.createTime.desc())
.fetch();
}
비공개가 false(=공개)인 부분만 조회하겠다!
요래 하면
@Test
void 공개_강의목록조회() throws InterruptedException {
LectureResponse lecture1 = createLecture(
"자바 배우기",
"자바, Spring을 통한 웹 개발 강의입니다.",
50000,
Category.Math,
teacher.getId()
);
LectureResponse lecture2 = createLecture(
"자바 응용하기",
"자바, Spring을 통한 웹 개발 실습강의입니다.",
50000,
Category.Math,
teacher.getId()
);
LectureResponse lecture3 = createLecture(
"과학 배우기",
"과학 강의입니다.",
50000,
Category.Science,
teacher.getId()
);
updateLectureToPublic(lecture1.id());
updateLectureToPublic(lecture2.id());
List<LectureListResponse> list = RestAssured
.given().log().all()
.when()
.get("/lectures")
.then().log().all()
.statusCode(200)
.extract()
.jsonPath()
.getList(".", LectureListResponse.class);
assertThat(list.size()).isEqualTo(2);
}
이런 테스트를 통과할것이다!
테스트 내용은
강의 등록을 3개 해놓고, 비공개된 강의를 공개로 2개만 바꿔놨을 때 잘 돌아가냐를 테스트 해봤다. -> 테스트 통과!