JPA Repository
필요JPARepository 상속 할 때는 제네릭스 타입으로
<EntityName, PKType>
- PK = id
- id type = Long
...
@Autowired
private QuestionRepository questionRepository;
@Test
void testJpa() {
Question question = new Question();
question.setSubject("sbb가 무엇인가요?"); // 제목
question.setContent("sbb에 대해서 알고 싶습니다."); // 내용
question.setCreateDate(LocalDateTime.now()); // 작성 시간
this.questionRepository.save(question); // 저장
Question question2 = new Question();
question2.setSubject("스프링부트 모델 질문입니다.");
...
}
...
@Test
void testJpa() {
List<Question> all = this.questionRepository.findAll(); // 저장된거 다 찾아와
assertEquals(2, all.size()); // 전체가 2일텐데 실제로도 맞나?
Question q = all.get(0); // 젤 처음꺼 가져와바
assertEquals("sbb가 무엇인가요?", q.getSubject()); // 젤 처음꺼 제목 저거일텐데 맞지?
}
@Test
void testJpa() {
Optional<Question> oq = this.questionRepository.findById(1); // id값 1번인거 가져와봐
if(oq.isPresent()) { // null 아니면
Question q = oq.get(); // 아까 찾은 1번 줘
assertEquals("sbb가 무엇인가요?", q.getSubject()); // 1번 제목 저거 맞지?
}
}
@Test
void testJpa() {
Question q = this.questionRepository.findBySubject("sbb가 무엇인가요?"); // 제목이거인거 찾아줘
assertEquals(1, q.getId()); // 이거 1번 맞지?
}
@Test
void testJpa() {
Question q = this.questionRepository.findBySubjectAndContent("sbb가 무엇인가요?", , "sbb에 대해서 알고 싶습니다."); // 제목이랑 내용 저거인거 찾아줘
assertEquals(1, q.getId()); // 이거 1번 맞지?
}
sbb%
: "sbb"로 시작하는 문자열%sbb
: "sbb"로 끝나는 문자열%sbb%
: "sbb"를 포함하는 문자열@Test
void testJpa() {
List<Question> qList = this.questionRepository.findBySubjectLike("sbb%"); // sbb로 시작하는 제목 찾아줘
Question q = qList.get(0); // 그 중에 젤 첫번째꺼 줘~
assertEquals("sbb가 무엇인가요?", q.getSubject()); // 그거 제목 이거 맞지?
}
assertTrue(값)
: 값이 true인지 테스트@Test
void testJpa() {
Optional<Question> oq = this.questionRepository.findById(1); // id 1번 찾기
assertTrue(oq.isPresent()); // 찾은게 null인지 아닌지 테스트
Question q = oq.get(); // 수정할 객체에 가져온 거 넣기
q.setSubject("수정된 제목"); // 수정할 내용 넣기
this.questionRepository.save(q); // 저장!
}
@Test
void testJpa() {
assertEquals(2, this.questionRepository.count()); // 총 두개인지 확인
Optional<Question> oq = this.questionRepository.findById(1); // id 1번 가져오기
assertTrue(oq.isPresent()); // null인지 아닌지 확인
Question q = oq.get(); // 삭제할 객체에 가져온 거 넣기
this.questionRepository.delete(q); // 삭제
assertEquals(1, this.questionRepository.count()); // 남은거 1개인지 확인
}
@Test
void testJpa() {
Optional<Question> oq = this.questionRepository.findById(2); // 2번 질문 가져오기
assertTrue(oq.isPresent()); // null 확인
Question q = oq.get(); // 가져온 것 객체에 담기
Answer a = new Answer();
a.setContent("네 자동으로 생성됩니다."); // 댓글 생성
a.setQuestion(q); // 어떤 질문의 답변인지 알기위해서 Question 객체가 필요
a.setCreateDate(LocalDateTime.now()); // 작성일시
this.answerRepository.save(a); // 저장
}
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());
이렇게 하면 테스트 실패 뜬다.
Question 조회 후 db세션 끝난다.
답변리스트가 q객체 조회할 때 가져와야 하는데, q.getAnswerList() 메서드 호출할 때 가져오기 때문에 실패가 뜬다.
이럴 때 데이터 가져오는 방식이 있는데, fetch=FetchType.EAGER
를 사용하면 된다.
@OneToMany
와 @ManyToOne
의 옵션
fetch=FetchType.LAZY
: 필요한 시점에 데이터 가져오는 방식fetch=FetchType.EAGER
: q 객체 조회할 때 답변 리스트 모두 가져오는 방식또 다른 방식으론 @Transactional
사용하는 것이다.
@Transactional
사용하면 메서드가 종료될 때까지 DB 세션이 유지되기 되기 때문에 해결된다.
@Transactional
@Test
void testJpa() {
...
// ex. findBySubject
Question findBySubject(String subject);
// ex. findBySubjectAndContent
Question findBySubjectAndContent(String subject, String content);
// ex. findBySubjectLike
List<Question> findBySubjectLike(String subject);
항목 | 설명 | 예제 |
---|---|---|
And | 여러 컬럼을 and 로 검색 | findBySubjectAndContent(String subject, String content) |
Or | 여러 컬럼을 or 로 검색 | findBySubjectOrContent(String subject, String content) |
Between | 컬럼을 between으로 검색 | findByCreateDateBetween(LocalDateTime fromDate, LocalDateTime toDate) |
LessThan | 작은 항목 검색 | findByIdLessThan(Integer id) |
GreaterThanEqual | 크거나 같은 항목 검색 | findByIdGraterThanEqual(Integer id) |
Like | like 검색 | findBySubjectLike(String subject) |
In | 여러 값중에 하나인 항목 검색 | findBySubjectIn(String[] subjects) |
OrderBy | 검색 결과를 정렬하여 전달 | findBySubjectOrderByCreateDateAsc(String subject) |
응답 결과가 여러건인 경우
에는 returnType을 Entity가 아닌 List<Entity>
로 해야 한다.
#JPA
# 메시지 호출 시 실행되는 쿼리 로그 보는 것
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.show_sql=true