5.1 데이터 조회 과정
DB에 저장된 데이터를 웹 페이지에 출력하는 과정
- 사용자가 데이터를 조회해 달라고 웹 페이지에서 URL 요청을 보냄
- 서버의 컨트롤러가 요청을 받아 해당 URL에서 찾으려는 데이터 정보를 리파지터리에 전달
- 리파지터리는 정보를 가지고 DB에 데이터 조회를 요청
- DB는 해당 데이터를 찾아 엔티티로 반환
- 반환된 엔티티는 모델을 통해 뷰 템플릿으로 전달됨
- 최종적으로 결과 뷰 페이지가 완성되어 사용자의 화면에 출력됨
5.2 단일 데이터 조회하기
URL 요청받기
DB에 저장한 데이터를 웹 페이지에서 보려면 해당 출력 페이지에 접속해야 함
URL 요청이 필요
게시글 n번 id를 조회할 때 localhost:8080/articles/n 에 접속하는 식으로 URL 요청을 받을 예정
아직 요청을 받아 줄 컨트롤러가 없기때문에 localhost:8080/articles/1000으로 접속하여도 아무것도 나오지 않음
컨트롤러 만들기
1. 조회할 데이터가 Article이므로 ArticleController에 코드를 추가하는 방식으로 작성
ArticleController 코드 열기
2. URL 요청을 받기 위해 기존 코드 맨 아래에 @GetMapping() 어노테이션 작성
괄호 안에 URL은 "/articles/{id}"로 입력
중괄호 안에 id를 써 주면 id는 변수로 사용됨
3. URL 요청을 받아 수행할 show()라는 메서드 생성
메서드의 매개변수는 URL에 있는 id를 가져옴 → id 앞에 @PathVariable 어노테이션 붙임
@PathVariable: URL 요청으로 들어온 전달값을 컨트롤러의 매개변수로 가져오는 어노테이션
@GetMapping("/articles/{id}")
public String show(@PathVariable Long id){
return "";
}
4. 로깅 기능을 이용하여 컨트롤러가 id를 잘 받았는지 확인
@GetMapping("/articles/{id}")
public String show(@PathVariable Long id){
log.info("id = " + id);
return "";
}
5. 서버 재시작 후 localhost:8080/articles/1000 에 접속
아직 결과 페이지는 나오지는 않지만 로그를 보면 id = 1000이 잘 전달된 것을 확인할 수 있음
데이터 조회해 출력하기
다음으로 해야 할 일 3단계
- id를 조회해 DB에서 해당 데이터 가져오기
- 가져온 데이터를 모델에 등록하기
- 조회한 데이터를 사용자에게 보여 주기 위한 뷰 페이지 만들고 반환하기
id를 조회해 데이터 가져오기
DB에서 데이터를 가져오는 주체는 리파지터리
@Autowired
private ArticleRepository articleRepository;
1. findById(Long id) 선택 → 특정 엔티티의 id 값을 지준으로 데이터를 찾아 Optional 타입으로 반환
일단 반환형을 무시하고 찾은 데이터를 Article 타입의 articleEntity 변수에 저장
// 1. id를 조회해 DB에서 해당 데이터 가져오기
Article articleEntity = articleRepository.findById(id);
2. 빨간색 물결로 에러표시가 뜸 → findBy(id) 로 찾은 값을 반환할 때 반환형이 Article이 아니기 때문.
반환형은 Optional<Article> 타입임
Optional<Article> 로 수정하면 에러가 사라지지만 다른 방법을 사용
코드 맨 뒤에 .orElse()메서드 추가 → id 값을 데이터를 찾을 때 해당 id가 없으면 null을 반환하라는 뜻
값이 존재하는 경우 articleEntity 변수에 값을 넣고 없으면 null을 저장
모델에 데이터 등록하기
articleEntity에 담긴 데이터를 모델에 등록
(MVC 패턴에 따라 조회한 데이터를 뷰 페이지에서 사용하기 위함)
1. 모델을 사용하기 위해 show() 메서드의 매개변수로 model 객체를 받아 옴
public String show(@PathVariable Long id, Model model){
(중략)
}
2. 모델에 데이터를 등록할 때 addAttribute() 메서드 사용
// 2. 가져온 데이터를 모델에 등록하기
model.addAttribute("article", articleEntity);
뷰 페이지 반환하기
1. 뷰 페이지는 articles라는 디렉터리 안에 show라는 파일이 있다고 가정하고 다음과 같이 반환
// 3. 조회한 데이터를 사용자에게 보여 주기 위한 뷰 페이지 만들고 반환하기
return "articles/show";
2. resources > templates > articles에 show.mustache 파일 생성
3. 헤더와 푸터 작성
{{>layouts/header}}
{{>layouts/footer}}
4. 헤더와 푸터 사이의 데이터를 부트스트랩을 활용하여 작성
gebootstrap.com 에 접속한 후 table 검색하여 Tables 클릭, 기본 형식의 테이블 [Copy]
5. show.mustache에서 헤더와 푸터 사이에 붙여 넣기
6. localhost:8080/articles/1000 페이지에 접속하여 확인
7. 표를 원하는 형태로 수정
- 제목 행의 이름 수정
- 필요 없는 코드 삭제
- 3번째 내용 행의 속성들은(scope="row", colspan="2") 모두 지우고 가짜 데이터를 임시로 넣음
{{>layouts/header}}
<table class="table">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Title</th>
<th scope="col">Content</th>
</tr>
</thead>
<tbody>
<tr>
<th>1</th>
<td>제목1111</td>
<td>내용1111</td>
</tr>
</tbody>
</table>
{{>layouts/footer}}
8. localhost:8080/articles/1000 페이지에서 출력 내용 확인
9. 모델에 등록한 article을 뷰 페이지에서 머스테치 문법에 따라 출력
{{#article}} {{/article}}로 사용 범위 지정
10. article에 담긴 id, title, content를 이중괄호를 이용해 가져옴
{{>layouts/header}}
<table class="table">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Title</th>
<th scope="col">Content</th>
</tr>
</thead>
<tbody>
{{#article}}
<tr>
<th>{{id}}</th>
<td>{{title}}</td>
<td>{{content}}</td>
</tr>
{{/article}}
</tbody>
</table>
{{>layouts/footer}}
11. 서버 재시작 후 localhost:8080/articles/3에 접속 → 아무런 데이터가 조회되지 않음
휘발성 DB인 메모리 DB를 사용하고 있기때문에 서버를 재시작할 때마다 데이터가 날아가 결과가 출력되지 않음
12. 데이터 추가 위해 localhost:8080/articles/new 페이지에서 제목과 내용 입력하고 [Submit] 클릭
1번 id를 가진 데이터가 만들어졌다고 나옴
13. localhost:8080/articles/1에 접속하면 에러 발생
엔티티에 기본 생성자 없어서 에러 발생
기본 생성자 추가하기
1. entity > Article 파일 열기
기본 생성자: 매개 변수가 아무것도 없는 생성자
2. 롬복 이용 → @NoArgsConstructor 를 추가하면 기본 생성자 코드를 작성하지 않아도 됨
3. 서버 재시작 후 localhost:8080/articles/new에 접속하여 제목과 데이터 입력 후 전송
4. localhost:8080/articles/1에 접속
5.3 데이터 목록 조회하기
단일 데이터를 조회할 땐 리파지터리가 엔티티를 반환했지만, 데이터 목록을 조회할 때는 엔티티의 묶음인 리스트를 반환
URL 요청받기
데이터 목록 조회는 localhost:8080/articles 라는 URL 요청이 들어왔을 때 처리하는 것으로 함
1. ArticleController 열고 show() 메서드 아래에 index() 메서드 추가, return 문에는 아직 아무것도 반환하지 X
public String index(){
return "";
}
2. index() 메서드에 @GetMapping("/articles") 선언하여 URL 요청을 받도록 함
@GetMapping("/articles")
public String index(){
return "";
}
데이터 조회해 출력하기
3단계로 나누어 코드 작성
- DB에서 모든 Article 데이터 가져오기
- 가져온 Article 묶음을 모델에 등록하기
- 사용자에게 보여 줄 뷰 페이지 설정하기
모든 데이터 가져오기
1. articleRepository 입력한 뒤 .을 찍은 후 findAll() 메서드 선택
findAll(): 해당 리파지터리에 있는 모든 데이터를 가져오는 메서드
메서드 수행 결과는 articleEntityList라는 이름으로 받음
타입은 데이터의 묶음을 받아오므로 List<Article> 로 설정
빨간 물결로 나옴
findAll() 메서드의 반환 데이터 타입: Iterable / 작성한 타입: List 로 불일치
해결하는 방법 3가지
- 캐스팅(형변환)
Iterable - Collection - List
캐스팅(형변환): 데이터 타입을 변환하는 것
업캐스팅: 넓은 범위로 해석하는 것
다운캐스팅: 좁은 범위로 해석하는 것 - List<Articㅅle> 을 Iterable<Article>로 업캐스팅
- findAll() 메서드가 Iterable이 아닌 ArrayList를 반환하도록 수정
세 번째 방법으로 코드 작성
2. com.example.firstproject > repository > ArticleRepository 열기
ArticleRepository가 CrudRepository 상속받음
CrudRepository의 메서드를 오버라이딩 해줌
블록 안 공간에서 우클릭 후 Generate → Override Methods 클릭한 후 findAll():Iterable<T> 선택
public interface ArticleRepository extends CrudRepository<Article, Long> {
@Override
Iterable<Article> findAll();
}
3. findAll() 메서드의 반환 값 타입을 Iterable에서 ArrayList로 바꿈
public interface ArticleRepository extends CrudRepository<Article, Long> {
@Override
ArrayList<Article> findAll();
}
4. ArticleController로 돌아오면 타입 불일치 문제가 해결된 것을 확인할 수 있음
모델에 데이터 등록하기
모델 사용
1. index() 메서드의 매개변수로 model 객체를 받아옴
2. model.addAttribute() 메서드로 articleEntityList를 "articleList" 라는 이름으로 등록
@GetMapping("/articles")
public String index(Model model){
// 1. 모든 데이터 가져오기
List<Article> articleEntityList = articleRepository.findAll();
// 2. 모델에 데이터 등록하기
model.addAttribute("articleList", articleEntityList);
// 3. 뷰 페이지 설정하기
return "";
}
뷰 페이지 설정하기
1. articles 디렉터리 안에 index.mustache 파일이 뷰 페이지로 설정될 수 있도록 return 문 작성
2. resources > templates > articles 에 index.mustache 파일 생성
3. 헤더, 푸터 작성
4. show.mustache 에서 헤더, 푸터 사이의 내용 복사하여 붙여 넣음
5. {{#article}} → {{#articleList}} 로 수정 (닫는 코드도 수정)
{{>layouts/header}}
<table class="table">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Title</th>
<th scope="col">Content</th>
</tr>
</thead>
<tbody>
{{#articleList}}
<tr>
<th>{{id}}</th>
<td>{{title}}</td>
<td>{{content}}</td>
</tr>
{{/articleList}}
</tbody>
</table>
{{>layouts/footer}}
6. 서버 재시작 한 후, localhost:8080/articles/new에 접속하여 제목과 내용 여러 개 추가
(재시작한 후 localhost:8080/articles에 들어가면 DB의 데이터가 날아간 상태이므로 먼저 데이터를 추가해주어야 함)
7. 인텔리제이 실행창에서 로그를 통해 데이터가 잘 들어갔는지 확인
8. localhost:8080/articles 에 접속하여 확인
mustache 문법
머스테치 문법에 쓴 변수(articleList)가 데이터 묶음인 경우 내부 코드가 반복됨
'백엔드 > 코딩 자율학습 스프링 부트 3 자바 백엔드 개발 입문 1~2장' 카테고리의 다른 글
4장. 롬복과 리팩터링 (0) | 2024.12.21 |
---|---|
3장. 게시판 만들고 새 그 작성하기: Create (0) | 2024.12.21 |
2장. MVC 패턴 이해와 실습 (0) | 2024.11.30 |
1장. 스프링 부트 시작하기 (0) | 2024.11.29 |