월루를 꿈꾸는 대학생

[Spring Boot] 리포지토리 본문

Programing/Spring Boot

[Spring Boot] 리포지토리

하즈시 2022. 12. 23. 11:50
728x90

리포지토리 

- 엔티티만으로 디비 저장이나 조회 못함 

- 디비랑 실제 연동할 jpa 리포지토리가 필요 

- 엔티티로 생성된 db 테이블에 접근하는 메서드 사용하기 위한 인터페이스 

- CRUD를 어떻게 처리할지 정의하는 계층 

 

import org.springframework.data.jpa.repository.JpaRepository;

//레포지토리 만들기 위해서 JpaRepositry 인터페이스 상속
//JpaRepositry 상속시 대상이 되는 엔티티 와 PK속성 넣어줘야함 ! = 규칙
public interface QuestionRepository extends JpaRepository<Question , Integer> {


}

 

public interface AnswerRepository extends JpaRepository<Answer ,Integer> {
}

 

테스트 코드에서 디비에 값 넣어보기 

// 테스트 클래스임을 정의
@SpringBootTest
class SbbApplicationTests {

   @Test
   void contextLoads() {
   }

   // DI 기능 객체를 스프링이 자동으로 생성해주고 생성해줌
   // 테스트는 Autowaired 쓰고 실제는 생성자를 통한 객체 주입 방식을 씀
   @Autowired
   private QuestionRepository questionRepository;
   @Test
   void testJpa(){
      Question q1 = new Question();
      q1.setSubject("sbb란? ");
      q1.setContent("sbb 개념과 구조에 대해서 알고 싶습니다");
      q1.setCreateDate(LocalDateTime.now());
      this.questionRepository.save(q1);

      Question q2 = new Question();
      q2.setSubject("스프링 부트란? ");
      q2.setContent("id는 자동 생성되나요? ");
      q2.setCreateDate(LocalDateTime.now());
      this.questionRepository.save(q2);

   }

}

 

 

 

 

데이터가 잘 들어갔는지 h2 에서 확인 


@Test
void testJpaFindAll(){
   // findAll 은 jpa가 가지고 있네 -> 데이터 조회시 사용
   List<Question> all = this.questionRepository.findAll();
   assertEquals(2,all.size());

   Question q = all.get(0);
   assertEquals("sbb란? ",q.getSubject());

}

 

 

id로 데이터 조회하기 

@Test
void testJpaFindById(){
   //findById - JPA 
   //Optional 쓰는 이유는 nnull처리르 유연하게 처리하기 위해서 
   Optional<Question> oq = this.questionRepository.findById(1);
   if(oq.isPresent()){
      Question q = oq.get();
      assertEquals("sbb란? ",q.getSubject());
   }
}

 

subject로 데이터 조회하기 

- 따로 메서드가 없기 때문에 인터페이스에 메서드 하나 만들어줘야함 

 

public interface QuestionRepository extends JpaRepository<Question , Integer> {

    // subject로 데이터 조회
    Question findBySubject(String subject);

}

 

@Test
void testJpaFindById(){
   //findById - JPA
   //Optional 쓰는 이유는 nnull처리르 유연하게 처리하기 위해서
   Optional<Question> oq = this.questionRepository.findById(1);
   if(oq.isPresent()){
      Question q = oq.get();
      assertEquals("sbb란? ",q.getSubject());
   }
}

 

인터페이스에서 선언부만 만들고 내용없는데도 잘 움직임 

-> JpaRepository 상속한 객체가 생성될 때 DI에 의해서 객체가 생성이됨 이 때 해당 객체의 메서드가 실행되는 경우 

안에 내용이 없어도 JPA가 메서드명을 보고 알아서 내용을 만들어줌  꿀 

 

요런식으로 신기방기  where에 서브젝트 있는 거 확인 

Hibernate: 
    select
        question0_.id as id1_1_,
        question0_.content as content2_1_,
        question0_.create_date as create_d3_1_,
        question0_.subject as subject4_1_ 
    from
        question question0_ 
    where
        question0_.subject=?

 

 

제목과 내용으로 조회하기

- And로 조건 조회 

 

역시 Question 인터페이스에다가 메서드 추가 

Question findBySubjectAndContent(String subject , String content);

 

@Test
void testJpaSubjectAndContent(){
   Question q = this.questionRepository.findBySubjectAndContent(
         "스프링 부트란? ","id는 자동 생성되나요? "
   );
   assertEquals(2,q.getId());
}

 

 

조합 모음 

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation

 

Spring Data JPA - Reference Documentation

Example 119. Using @Transactional at query methods @Transactional(readOnly = true) interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") void del

docs.spring.io

 

 

 

특정 문자가 포함된 레코드 찾기 

@Test
void testJpaSubjectLike(){
   List<Question> qList = this.questionRepository.findBySubjectLike("sbb%");
   Question q = qList.get(0);
   assertEquals("sbb란? ", q.getSubject());
}

sbb%: "sbb"로 시작하는 문자열
%sbb: "sbb"로 끝나는 문자열
%sbb%: "sbb"를 포함하는 문자열

 

레코드 수정하기

@Test
void testUpdate(){
   Optional<Question> oq = this.questionRepository.findById(1);
   assertTrue(oq.isPresent());
   Question q = oq.get();
   q.setSubject("수정된 제목");
   this.questionRepository.save(q);
}

 

 

데이터 삭제하기 

@Test
void testDelete(){
   assertEquals(2,this.questionRepository.count());
   Optional<Question> oq = this.questionRepository.findById(1);
   assertTrue(oq.isPresent());
   Question q = oq.get();
   this.questionRepository.delete(q);
   assertEquals(1,this.questionRepository.count());
   
}

 

 

답변 생성하기 

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

    Answer a = new Answer();
    a.setContent("네 자동으로 생성됩니다.");
    a.setQuestion(q); // 어떤 질문의 답변인지 알기 위해 필요
    q.setCreateDate(LocalDateTime.now());
    this.answerRepository.save(a);
}

 

 

답변 조회 

@Test
void selectAnswer(){
    Optional<Answer> oa = this.answerRepository.findById(1);
    assertTrue(oa.isPresent());
    Answer a = oa.get();
    assertEquals(2,a.getQuestion().getId());
}

 

 

질문에서 답변 찾기 

//질문에서 답변 찾기
@Test
void selectQuestionToAnswer(){
    Optional<Question> oq = this.questionRepository.findById(2);
    assertTrue(oq.isPresent());
    Question q = oq.get();

    List<Answer> answerList = q.getAnswerList();

    assertEquals(1,answerList.size());
    assertEquals("네 자동으로 생성됩니다.", answerList.get(0).getContent());

}

 

 

해당 오류 나옴 
failed to lazily initialize a collection of role: com.example.sbb.Question.answerList, could not initialize proxy - no Session


출처

https://wikidocs.net/160890

 

2-05 리포지터리

* `[완성 소스]` : [https://github.com/pahkey/sbb3/tree/2-05](https://github.com/pahkey/sbb3/tree/2-05) …

wikidocs.net

 

728x90