5일차
~5.3 데이터 목록 조회하기(종이책 p.153~182)
5장 게시글 읽기: Read
5.1 데이터 조회 과정

5.2 단일 데이터 조회하기
먼저 localhost:8080/articles/new 페이지에서 제목과 내용을 입력한 후 Submit 하여 DB에 저장
URL 요청받기
DB에 저장한 데이터를 웹 페이지에서 보려면 해당 출력 페이지에 접속해야 한다. 그러기 위해선 URL 요청이 필요하다.
여기에서는 1번 id를 조회할 때 localhost:8080/articles/1 과 같은 형식으로 조회하도록 한다.
articles/id 로 요청했을 때 이를 받아 줄 컨트롤러를 만들어야한다.
- 조회할 데이터가 Article이므로 ArticleController 코드에 추가로 작성한다.
- @GetMapping() 어노테이션을 작성하고 괄호 안에 “/articles/{id}”를 입력한다.
- 중괄호 안에 id를 써주면 id는 변수로 사용된다.
- URL 요청을 받아 수행할 show() 메서드를 만든다.
- 메서드의 매개변수는 URL에 있는 id를 가져오는데, id 앞에 @PathVariable 어노테이션을 붙인다.
- @PathVariable 어노테이션은 URL 요청으로 들어온 전달값을 컨트롤러의 매개변수로 가져온다.
- id를 잘 받아오는지 확인하기 위해 로깅 기능을 넣는다.
데이터 조회해 출력하기
다음과 같은 3가지 단계로 이루어진다.
- id를 조회해 DB에서 해당 데이터 가져오기
- 가져온 데이터를 모델에 등록하기
- 조회한 데이터를 사용자에게 보여 주기 위한 뷰 페이지 만들고 반환하기
● id를 조회해 데이터 가져오기
DB에서 데이터를 가져오는 주체는 리파지터리이다.
- findById(Long id)를 이용해 찾은 데이터를 Article 타입의 articleEntity 변수에 저장한다.
- findById()는 JPA의 CrudRepository가 제공하는 메서드로, 특정 엔티티의 id값을 기준으로 데이터를 찾아 Optional 타입으로 반환한다.
- articleRepository까지 입력하고 점(.)을 찍으면 사용할 수 있는 메서드 목록이 나오는데 그 중 findById(Long id)를 선택한다.
- findById로 찾은 값을 Article 타입으로 반환하지 않아서 오류가 생기기 때문에 맨 뒤에 .orElse() 메서드를 추가하고 매개변수로 null값을 넣는다.
- id값으로 데이터를 찾을 때 해당 id값이 없으면 null을 반환하라는 뜻이다.
- 반환형은
Optional<Article> 타입이다. Article을 Optional<Article>로 수정해도 오류가 없어진다.
● 모델에 데이터 등록하기
-
모델을 사용하기 위해 show() 메서드의 매개변수로 model 객체를 받아온다.
-
article이라는 이름으로 articleEntity 객체를 등록한다.
- 모델에 데이터를 등록할 때는 addAttribute() 메서드를 사용한다.
// name이라는 이름으로 value 객체 추가
model.addAttribute(String name, Object value)
● 뷰 페이지 반환하기
- articles라는 디렉터리 안에 show라는 파일이 있다고 가정하고 return “articles/show”; 로 반환한다.
- resources/templates/articles 에 show.mustache 파일을 만든다.
- 헤더와 푸터를 넣는다.
- 그 사이에 보고 싶은 데이터를 부트스트랩을 활용하여 작성한다.
- getbootstrap.com 에 접속 후 table을 검색하고 소스 코드를 복사해서 붙여넣는다.
- 제목 행의 이름을 수정하고, 필요 없는 코드를 삭제 후, 3번째 내용 행에 속성들은 지우고 가짜 데이터를 임시로 넣고 실행해보면 가짜 데이터가 잘 출력되는 모습을 확인할 수 있다.
- 모델에 등록한 article을 뷰 페이지에서 머스테치 문법인 이중중괄호({{}})를 이용해 출력한다.
- {{#article}}{{/article}} 과 같이 샵(#)을 이용해 열고 슬래시(/)를 이용해 닫는다.
- 이렇게 가져온 데이터를 여러 행에 걸쳐 사용할 때는 어디에서 어디까지 사용할지 범위를 지정한다.
- article의 사용 범위를 지정했으니 article에 담긴 id, title, content를 이중중괄호({{}})를 이용해 가져온다.

메모리 DB, 휘발성 DB를 사용하기 때문에 다시 데이터를 저장하고 서버를 시작해서 localhost:8080/articles/1 로 접속해보면 에러가 나고, No default constructor for entity: ・・・ entity.Article 메시지를 확인할 수 있다.
● 기본 생성자 추가하기
- 기본 생성자를 추가하기 위해 entity/Article 파일을 연다.
- 롬복을 활용해 @NoArgsConstructor 어노테이션을 추가해주면 기본 생성자를 추가해 준다.
- 서버를 재시작하고 데이터를 추가후 articles/1을 확인해보면 잘 나오는 것을 확인할 수 있다.

5.3 데이터 목록 조회하기
단일 데이터가 아닌 여러 데이터일 경우 데이터 목록을 조회하는 법에 대해서 공부한다.
단일 데이터와 방법은 같지만 다른 점은 리파지터리가 엔티티를 반환하는게 아니라 엔티티의 묶음인 리스트를 반환한다는 것이다.
URL 요청받기
- ArticleController의 show() 메서드 아래에 index() 메서드를 추가하고 return문에서는 일단 아무것도 반환하지 않는다.
- @GetMapping(”/articles)를 선언해 URL 요청을 받도록 한다.
데이터 조회해 출력하기
단일 데이터를 조회할 때와 마찬가지로 3가지 단계로 나눈다.
- DB에서 모든 Article 데이터 가져오기
- 가져온 Article 묶음을 모델에 등록하기
- 사용자에게 보여 줄 뷰 페이지 설정하기
● 모든 데이터 가져오기
-
DB에서 데이터를 가져오려면 리파지터리가 필요하다. articleRepository를 입력하고 점(.)을 찍은 후 findAll() 메서드를 선택한다.
- findAll() 메서드는 해당 리파지터리에 있는 모든 데이터를 가져오는 메서드이다.
List<Article> articleEntityList = articleRepository.findAll();
-
findAll() 메서드는 Iterable 데이터 타입을 반환하기 때문에 타입이 불일치한다는 오류가 발생한다. 다음과 같은 3가지 방법으로 해결할 수 있다.
-
캐스팅(형변환) 하기
- 캐스팅(casting)이란 데이터 타입을 변환하는 것을 말하며 형변환이라고도 한다. 넓은 범위로 해석하는 것을 업캐스팅(upcasting), 좁은 범위로 해석하는 것을 다운캐스팅(downcasting)이라고 한다.

Iterable, Collection, List 인터페이스의 상하 관계는 다음과 같다. Iterable이 가장 상위 인터페이스이므로 코드를 다음과 같이 수정하면 Iterable<Article>을 List<Article>로 다운캐스팅 할 수 있다.
List<Article> articleEntityList = (List<Article>) articleRepository.findAll();
-
articleEntityList의 타입을 findAll() 메서드가 반환하는 타입으로 맞추기
List<Article>을 Iterable<Article>로 업캐스팅해준다.
Iterable<Article> articleEntityList = articleRepository.findAll();
-
ArrayList 이용하기
- findAll() 메서드가 Iterable이 아닌 ArrayList를 반환하도록 수정
- 책에서는 이 방법으로 수정했다.
- com.example.firstproject/repository/ArticleRepository 를 연다.
- CrudRepository를 상속하고 있으므로 CrudRepository의 메서드를 오버라이딩 해준다.
- 마우스 오른쪽 버튼을 누르고 Generate → Override Methods를 클릭하고
findAll():Iterable<T>를 선택한다.
- 추가한 코드를 보면 기본적으로
<Article>의 Iterable 타입으로 반환하게 되어있는데 이것을 ArrayList로 바꾼다.
● 모델에 데이터 등록하기
- index() 메서드의 매개변수로 model 객체를 받아 온다.
- model.addAttribute() 메서드로 articleEntityList를 “articleList”라는 이름으로 등록한다.
● 뷰 페이지 설정하기
- index.mustache 파일이 뷰 페이지로 설정되도록 return “articles/index”; 라고 작성한다.
- index.mustache 파일을 작성한다.
- resources/templates/articles에 index.mustache 파일을 생성한다.
- 헤더와 푸터를 작성한다.
- 그 사이에 show.mustache에서 썼던 테이블 코드를 복사하여 붙여넣는다.
- 여는 코드와 닫는 코드를 {{#articleList}}, {{/articleList}}로 수정한다.
서버를 재실행하고 데이터를 넣어준 후 localhost:8080/articles에서 확인해 보면 데이터가 잘 출력되는 모습을 확인할 수 있다.

※ index.mustache 코드를 보면 {{#articleList}}{{/articleList}} 코드가 있는데, 이렇게 머스테치 문법에 쓴 변수(articleList)가 데이터 묶음인 경우 마치 for문처럼 내부 코드가 반복된다.