BoardPersistRepository
em.find(Board.class, id)를 찾으면, Board 로 바꾼다.
public Board findById(int id) { em.find(Board.class, id); //앞이 클래스, 뒤가 pk return board; }
이러면 끝….. em.find는 Persistence Context (PC)에서 찾는다는 것!
findAll 메소드에서는 여러 개의 결과를 반환해야 하기 때문에 EntityManager의 find 메소드를 사용할 수 없다. find 메소드는 단일 엔티티 객체를 조회할 때 사용되며, 주로 특정 ID를 가진 엔티티를 찾을 때 사용된다.
em.find ?
DB한테 요청하는게 아니라, PC한테 1번 PK키를 가지고 있는 오브젝트가 있는지 BR이 물어보는 것! (nativeQuery는 그냥 던지는 것. 복잡한 쿼리는 nativeQuery로 던져야함!)
1번을 찾으러 갔는데 현재 pc에서는 존재하지 않음 (pc를 캐싱의 용도로 사용할 수도 있다.) 보드 객체가 있는지, 영속화된 보드 객체가 있는지 찾으러 갔는데 없음 why? 최초의 pc는 항상 비어있기 때문이다. 외부에서 요청하면 웹은 모든 요청을 새로운 사람으로 인식하니까, request할 때마다 비어있다. 없으니까 1번 조회 쿼리가 db에 날아감. pk키가 id라는 걸 알고 있어서 쿼리문이 알아서 자동 발동! (pc에 없을 시) 찾은 정보를 Board클래스를 new를 해서 만들어줌. -> 디폴트 컨스트럭트 (엔티티의 기본 생성자)를 때린다. PC에 없으면 조회하기 위해 select 쿼리가 날아감 db가 응답하면 db에서 조회했기 때문에 pk키가 있는 Board객체를 PC에 줌. 그렇게 BR이 Board를 받는 것 ! 클라이언트까지 응답이 완료되면 초기화. pc는 다 비워진다.
[ 조회가 2번 일어나면 캐싱이 된다 ]
컨트롤러가 1번 PK 조회를 2번 때리면, 이번엔 캐싱이 된다! (PC에서 들고 있으니까!) (= 조회가 2번 일어나면 캐싱이 된다!!!) 그럼 쿼리가 날아가는게 아니라, pc에서 pk키가 1번인 애들을 뒤져보게 된다. 바로 들고올 수 있으니까 쿼리 발동 XXX
정말 2번 때리면 쿼리가 2번 날아가는지 검증도 해봐야 한다. (궁금하지 않니?)
일반적으로 테스트 해보기
@Test public void findById_test() { // given int id = 1; // when Board board = boardPersistRepository.findById(id); System.out.println("findById_test " + board); // then // org.assertj.core.api assertThat(board.getTitle()).isEqualTo("제목1"); assertThat(board.getContent()).isEqualTo("내용1"); }
동일한 id를 조회하면 어떻게 될까?
@Test public void findById_test() { // given int id = 1; // when Board board = boardPersistRepository.findById(id); boardPersistRepository.findById(id); System.out.println("findById_test " + board); // then // org.assertj.core.api assertThat(board.getTitle()).isEqualTo("제목1"); assertThat(board.getContent()).isEqualTo("내용1"); }
동일한 id를 조회해서, 캐싱이 되었기 때문에 1번 달아가는 쿼리!
em.clear(); (2회 날리는 쿼리)
@Test public void findById_test() { // given int id = 1; // when Board board = boardPersistRepository.findById(id); em.clear(); //비우기 boardPersistRepository.findById(id); System.out.println("findById_test " + board); // then // org.assertj.core.api assertThat(board.getTitle()).isEqualTo("제목1"); assertThat(board.getContent()).isEqualTo("내용1"); }
em.clear를 사용해서 PC를 비웠기 때문에 쿼리가 2번 날아간다.
사용할 필요 없음!
+)
각각 하나씩 …
BoardController
@GetMapping("/board/{id}") public String detail(@PathVariable Integer id, HttpServletRequest request) { Board board = boardPersistRepository.findById(id); request.setAttribute("board", board); return "board/detail"; }
Share article