사이먼's 코딩노트
[SpringBoot] Repository로 DB 관리하기(2) 본문
[Repository로 DB 관리하기]
- QuestionRepository.java와 AnswerRepository.java 클래스를 생성하고 SbbApplicationTests.java 클래스를 통해 테스트 형식으로 질문 데이터를 새로 생성하여 직접 DB에 저장해보는 작업을 마쳤다.
- 이번에는 그 외의 여러가지 DB 관리하는 방법인 저장, 조회, 수정, 삭제를 하는 방법을 알아봅시다.
- 현재까지 진행된 작업으로 실제 DB에 저장된 question 데이터들은 아래 사진과 같다.
[findAll]
- findAll() 메서드는 question 테이블에 저장된 모든 데이터를 조회하는 역할을 한다.
- findAll() 메서드는 이미 QuestionRepository의 부모 격인 JpaRepository의 내장 메서드로서 따로 메서드를 선언할 필요는 없다.
- 아래와 같이 SbbApplicationTests.java 클래스에 코드를 추가하고 실행해보면 원하는 question 데이터 조회가 성공적으로 이루어진다.
List<Question> all = this.questionRepository.findAll();
assertEquals(2, all.size());
Question q = all.get(0);
assertEquals("sbb가 무엇인가요?", q.getSubject());
- findAll() 을 통해 모든 question 데이터를 all 이라는 List에 담고, assertEquals(2, all.size()) 를 통해 총 2개의 question 데이터를 조회한다.
- 이 때, 2라고 작성된 부분은 expected인 기댓값이며, 현재 진행하는 작업은 조회가 정상적으로 작동하는 지 확인을 하기 위한 테스트이기 때문에 반드시 기댓값과 실제 question의 데이터 개수가 맞아야만 테스트가 정상적으로 진행된다.
- 만약에 question 데이터가 총 3개가 들어있다면, 기댓값을 2대신 3을 작성해야한다.
- List를 사용했기 때문에 all.get(0)을 통해 0번째 index인 1번 question 데이터를 가져오고, assertEquals("sbb가 무엇인가요?", q.getSubject()); 를 통해 id가 1인 question의 subject가 'sbb가 무엇인가요?'와 일치한 지 확인한다.
- 이 때, sbb가 무엇인가요? 라고 작성된 부분도 expected인 기댓값이다.
- findAll() 메서드는 DB 쿼리로 생각했을 때 "SELECT * FROM question" 과 의미가 같다.
[findById]
- findById() 메서드는 question 테이블에 저장된 데이터 중, id 값을 조건으로 삼아 조회하는 역할을 한다.
- findById() 메서드도 이미 JpaRepository의 내장 메서드로서 따로 메서드를 선언할 필요는 없다.
- 아래와 같이 SbbApplicationTests.java 클래스에 코드를 추가하고 실행해보면 원하는 id 값에 맞는 question 데이터 조회가 성공적으로 이루어진다.
Optional<Question> oq = this.questionRepository.findById(1);
if(oq.isPresent()) {
Question q = oq.get();
assertEquals("sbb가 무엇인가요?", q.getSubject());
}
- findById() 메서드에서는 Optional이라는 형식을 사용하게 되는데 Optional은 무조건 0개 아니면 1개를 조회하게 된다.
- Optional를 사용하게 되면 우아한 처리가 가능하게 되는데, 이 때 말하는 우아한 처리란 null 값이 포함되어 있어도 안전하게 처리가 가능하다는 뜻이다.
- findById(1)을 통해 id가 1인 question 데이터를 가져오고, 해당 데이터의 subject가 'sbb가 무엇인가요?' 와 일치한 지 확인한 다음, 일치한다면 테스트에 성공하게 된다.
- findById(1) 메서드는 DB 쿼리로 생각했을 때 "SELCET * FROM question WHERE id = 1" 과 의미가 같다.
[findBySubject]
- findBySubject() 메서드는 question 테이블에 저장된 데이터 중, subject 값을 조건으로 삼아 조회하는 역할을 한다.
- findBySubject() 메서드는 JpaRepository의 내장 메서드가 아니기 때문에, QuestionRepository.java 클래스에 해당 메서드를 선언해줘야 한다.
- 아래와 같이 QuestionRepository.java와 SbbApplicationTests.java 클래스에 코드를 추가하고 실행해보면 원하는 subject 값에 맞는 question 데이터 조회가 성공적으로 이루어진다.
public interface QuestionRepository extends JpaRepository<Question, Integer> {
Question findBySubject(String subject);
}
Question q = this.questionRepository.findBySubject("sbb가 무엇인가요?");
assertEquals(1, q.getId());
- findBySubject() 메서드를 통해 'sbb가 무엇인가요?' 라는 subject를 가진 question 데이터를 찾아 q라는 변수에 저장한다.
- assertEquals(1, q.getId());를 통해 찾고자하는 question 데이터가 1개이면서 해당 데이터의 Id를 가져오면 테스트에 성공하게 된다.
- findBySubject("sbb가 무엇인가요?") 메서드는 DB 쿼리로 생각했을 때 "SELECT * FROM question WHERE subject = 'sbb가 무엇인가요?'" 와 의미가 같다.
[findBySubjectAndContent]
- findBySubjectAndContent() 메서드는 question 테이블에 저장된 데이터 중, subject 값과 content 값을 AND 조건으로 삼아 조회하는 역할을 한다.
- findBySubjectAndContent() 메서드는 JpaRepository의 내장 메서드가 아니기 때문에, QuestionRepository.java 클래스에 해당 메서드를 선언해줘야 한다.
- 아래와 같이 QuestionRepository.java와 SbbApplicationTests.java 클래스에 코드를 추가하고 실행해보면 원하는 조건에 맞는 question 데이터 조회가 성공적으로 이루어진다.
public interface QuestionRepository extends JpaRepository<Question, Integer> {
Question findBySubject(String subject);
Question findBySubjectAndContent(String s, String s1);
}
Question q = this.questionRepository.findBySubjectAndContent(
"sbb가 무엇인가요?", "sbb에 대해서 알고 싶습니다.");
assertEquals(1, q.getId());
- findBySubjectAndContent() 메서드를 통해 'sbb가 무엇인가요?' 라는 subject와 'sbb에 대해서 알고 싶습니다' 라는 content를 가진 question 데이터를 찾아 q라는 변수에 저장한다.
- assertEquals(1, q.getId());를 통해 찾고자하는 question 데이터가 1개이면서 해당 데이터의 Id를 가져오면 테스트에 성공하게 된다.
- findBySubjectAndContent("sbb가 무엇인가요?", "sbb에 대해서 알고 싶습니다.") 메서드는 DB 쿼리로 생각했을 때 "SELECT * FROM question WHERE subject = 'sbb가 무엇인가요?' AND content = 'sbb에 대해서 알고 싶습니다.'"와 의미가 같다.
[question 데이터 수정하기]
- 이번에는 question 데이터를 수정하는 방법을 Repository를 통해 수행해봅시다.
- 데이터를 수정할 때는 추가할 메서드는 없고, findById()를 통해 수정하고 싶은 question 데이터를 가져와서 해당 컬럼의 값을 수정해주면 된다.
- 아래와 같이 SbbApplicationTests.java 클래스에 코드를 추가하고 실행해보면 수정하고 싶은 question 데이터의 subject 값의 수정이 성공적으로 이루어진다.
Optional<Question> oq = this.questionRepository.findById(1);
assertTrue(oq.isPresent());
Question q = oq.get();
q.setSubject("수정된 제목");
this.questionRepository.save(q);
- Optional 형식으로 findById(1) 메서드를 사용하여 id가 1인 question 데이터를 oq라는 변수에 저장한다.
- Optional을 사용했을 때는 oq.get()과 같이 한 번 더 데이터를 가져와야 한다.
- q.setSubject("수정된 제목") 을 통해 해당 데이터의 subject 값을 '수정된 제목' 으로 수정한다.
- 마지막엔 this.questionRepository.save(q)를 통해 수정된 값을 저장한다.
- 실제 클래스를 실행해보면 바로 UPDATE 문을 통해 데이터가 수정되는 것이 아니라, SELECT 문을 통해 먼저 데이터를 조회하는 과정이 존재한다.
- DB 쿼리로 생각했을 때 "UPDATE question SET subject = '수정된 제목' WHERE id = 1" 과 의미가 같다.
- 아래 사진은 실제로 실행했을 때 DB에서 조회한 결과, 수정된 데이터를 나타낸다.
[question 데이터 삭제하기]
- 이번에는 question 데이터를 삭제하는 방법을 Repository를 통해 수행해봅시다.
- 데이터를 삭제할 때는 추가할 메서드는 없고, findById()를 통해 삭제하고 싶은 question 데이터를 가져와서 해당 데이터를 삭제해주면 된다.
- 아래와 같이 SbbApplicationTests.java 클래스에 코드를 추가하고 실행해보면 삭제하고 싶은 question 데이터의 삭제가 성공적으로 이루어진다.
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());
- Optional 형식으로 findById(1) 메서드를 사용하여 id가 1인 question 데이터를 oq라는 변수에 저장한다.
- Optional을 사용했기 때문에 oq.get()과 같이 한 번 더 데이터를 가져와야 한다.
- this.questionRepository.delete(q)를 통해 q에 담긴 id가 1인 데이터를 삭제한다.
- 실제 클래스를 실행해보면 바로 DELETE 문을 통해 데이터가 삭제되는 것이 아니라, SELECT 문을 통해 먼저 데이터를 조회하는 과정이 존재한다.
- 이 때, 실제 DB 데이터를 삭제하지 않고 테스트가 성공적으로 이루어졌는 지 확인하고 싶다면 클래스에 @Transactional과 @Rollback 어노테이션을 추가한다.
- DB 쿼리로 생각했을 때 "DELETE FROM question WHERE id = 1" 과 의미가 같다.
- 아래 사진은 어노테이션을 적용하지 않고 실행했을 때, 실제로 DB에서 조회한 결과, 데이터가 삭제된 모습을 볼 수 있다.
반응형
'Java > SpringBoot' 카테고리의 다른 글
[SpringBoot] Thymeleaf / 데이터 전달 및 랜더링 / Redirect (0) | 2024.05.08 |
---|---|
[SpringBoot] Repository로 DB 관리하기(3) (0) | 2024.05.07 |
[SpringBoot] DB 테이블 매핑 / Repository로 DB 관리하기(1) (0) | 2024.05.07 |
[SpringBoot] Spring Security / JPA (0) | 2024.05.06 |
[SpringBoot] Java Spring Boot (0) | 2024.05.03 |