본문 바로가기
Spring

2022-09-26 스프링 (리포지터리) 데이터 조회,수정,삭제 및 답변 생성 및 저장, 조회

by allwing12 2022. 9. 26.
    @Test
   void getQuestionsBySubjectsAndContent() {
      List<Question> question = this.questionRepository.findBySubjectAndContent(
            "sbb가 무엇인가요?", "sbb에 대해서 알고 싶습니다.");
      assertEquals(4,question.size());
   }
   @Test
   void getQuestionsBySubjectLike() {
      List<Question> question = this.questionRepository.findBySubjectLike("%sbb%");
      assertEquals(4,question.size());
   }
   @Test
   void updateQuestion() {
      Optional<Question> oq = questionRepository.findById(2);
      if(oq.isPresent()) {
         Question question = oq.get();
         question.setSubject("수정된 질문");
         question.setContent("수정된 내용");
         questionRepository.save(question);
      }
   }
   
   @Test
	void deleteQuestion() {
		assertEquals(5, questionRepository.count());
		Optional<Question> oq = questionRepository.findById(1);
		if(oq.isPresent()) {
			Question question = oq.get();
			questionRepository.delete(question);
		}
		assertEquals(4, questionRepository.count());
	}
}

 

해당 부분은 subject와 content에 원하는 부분만 조회하는 것이다.

원하는 부분만 조회할 때에는 findBySubjectAndContent를 사용하면 된다.

 

그리고 그 다음은 findBySubjectLike 라고 해서 원하는 문자가 들어간 부분만 조회를 하는 것이다.

여기에서 %sbb%라고 썼는데 이 부분은 

sbb% 라고 썼을 때에는 sbb로 시작하는 문자열을 원할 때 사용하며

%sbb는 sbb로 끝나는 문자열을 원할 때 

%sbb% 는 sbb를 포함하는 문자열을 원할 때 사용하는 것이다.

 

그리고 밑에는 updateQuestion에서는 말 그대로 내가 원하는 것으로 subject와 content를 수정하는 것이다.

Optional을 사용하였는데 Optional의 경우에는 나중에 차차 한 번 정리 해보겠다.

 

그리고 맨 밑은 원하는 질문에 대해서 삭제하는 쿼리이다.

id값으로 삭제하는 쿼리이다.

 

 

 

@Test
	void createAnswer() {
		Optional<Question> oq = questionRepository.findById(2);
		if(oq.isPresent()){
			Question question = oq.get();

			Answer answer = new Answer();
			answer.setContent("답변입니다");
			answer.setQuestion(question);
			answer.setCreateDate(LocalDateTime.now());
			answerRepository.save(answer);

		}
	}

 

이건 id 값에 답변을 다는 쿼리라고 생각하면 된다.

answer도 똑같이 answerRepositiory에 저장까지 한 상태이고 question과 똑같은 상태로 만들어야한다.

dao 라는 패키지도 있어야하고 그 패키지 안에 내용을 question 과 같지만 answer로 해서 만들어야한다.

이렇게까지 하면 id 값이 2번것에 "답변입니다" 하면서 달린다고 생각하면 된다.

이렇게 해서 답변 생성과 저장까지 완료를 했다.

 

 

 

현재까지 만든 패키지와 클래스들은 위의 사진과 같다.

 

 

    @Test
   @Transactional
// void selectAnswer() {
//    Optional<Answer> oa = answerRepository.findById(2);
//    if (oa.isPresent()) {
//       Answer a = oa.get();
//       assertEquals(2, a.getId());
//    }
// }
   void selectAnswer() {
      Optional<Question> oq = questionRepository.findById(1);
      if(oq.isPresent()) {
         Question question = oq.get();
         List<Answer> answerList = question.getAnswerList();
         assertEquals(1,answerList.size());
      }
   }

 

답변을 달고 저장까지 했는데 이제는 그 답변을 조회하는 방식이다.

주석처리 한 곳과 아닌 곳은 내가 교재를 보고 그 교재에 나온 방식이며 밑에는 강사님께서 푼 방식이다.

@Transactional 이 있는데 어쨋든 결과에 join 이라는 것을 활용해서 조회를 한다.

그리고 만약 @Transactional을 안쓰면 에러가 발생하게 되는데 그 이유는

 

 

저 LAZY 라는 애 떄문인데 저 LAZY는 Question 클래스에 OneToMany 라는 것을 까보면

저렇게 쭉 나오게 되는데 fetch 타입이 LAZY라고 나오는데 얘는 하나하나 불러오기 때문에

에러가 발생을 하는거라고 한다, 이게 무슨 소리냐 위에서 코드를 보면 questionRepository로

findById를 해서 조회를 하는데 이 부분을 지나면 question 자체가 없어져서 조회를 못한다고 한다.

그래서 이 부분을 똑같이 answer 클래스를 조회해보면 fetch 타입이 EAGER로 나오는데

fetch 타입 자체를 EAGER로 바꿔줘야 한다고 한다.

 

 

근데 내가 주석처리 한대로 해도 조회는 된다.

 

 

댓글