Notice
Recent Posts
Recent Comments
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

충분히 쌓여가는

게시글 읽기 Read 본문

Spring/게시판 만들기

게시글 읽기 Read

빌드이너프 2023. 9. 12. 15:33

articles/id로 URL 요청을 했을 때 이를 받아 줄 Controller 만들기

com.example.firstproject>controller>ArticleController에서 URL 요청을 받기 위해 @GetMapping() 어노테이션 작성

URL은 id에 따라 /article1, /article2, ... 등으로 받기로 했기 때문에 "/articles/{id}"라고 입력한다

@GetMapping("/articles/{id}")

 

URL 요청을 받아 수행할 show()라는 메서드 생성

메서드의 매개변수는 URL에 있는 id를 가져ㅛ오는데, id 앞에 @PathVariable 어노테이션을 붙인다

@PathVariable: URL 요청으로 들어온 전달값을 Controller의 매개변수로 가져오는 어노테이션

package com.example.firstproject.controller;

import com.example.firstproject.dto.ArticleForm;
import com.example.firstproject.entity.Article;
import com.example.firstproject.repository.ArticleRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

@Slf4j
@Controller
public class ArticleController {
    @Autowired
    private ArticleRepository articleRepository;

    @GetMapping("/articles/new")
    public String newArticleForm() {
        return "articles/new";
    }

    @PostMapping("/articles/create")
    public String createArticle(ArticleForm form) {
        log.info(form.toString());

        // 1. DTO를 entity로 변환하기
        Article article = form.toEntity();
        log.info(article.toString());

        // 2. Repository로 엔티티를 DB에 저장
        Article saved = articleRepository.save(article);
        log.info(saved.toString());
        return "";
    }

    @GetMapping("/articles/{id}")
    public String show(@PathVariable Long id) {
        return "";
    }
}

 

log 기능으로 id를 잘 받았는지 출력

localhost:8080/articles/1000 을 URL에 입력 후 Run 결과 확인

 

여기까지 서버의 Controller가 URL 요청을 받는 것까지 확인


 

데이터 조회하여 출력

1. id를 조회해 DB에서 해당 데이터 가져오기

DB에서 데이터를 가져오는 주체는 repository, repository의 구현 객체는 @Autowired 어노테이션으로 주입받음

articleRepository에 점(.)을 찍으면 사용할 수 있는 메서드 중 findById(Long id) 선택

findById: JPA의 CrudRepository가 제공하는 메서드로, 특정 entity id 값을 기준으로 데이터를 찾아 Optional 타입으로 반환

Article 타입의 articleEntity 변수에 저장

 

반환형이 Article이 아니라서 에러표시 생김, 반환형은 Optional<Article>

자바8 이후부터 사용가능

 

다른 방법으로 .orElse() 메서드 추가 후 매개변수로 null 값 넣기

=> id 값으로 데이터를 찾을 때 id 값이 없으면 null을 반환하라는 뜻(데이터를 조회한 결과, 값이 있으면 articleEntity 변수에 값을 넣고, 없으면 null을 저장)

package com.example.firstproject.controller;

import com.example.firstproject.dto.ArticleForm;
import com.example.firstproject.entity.Article;
import com.example.firstproject.repository.ArticleRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

@Slf4j
@Controller
public class ArticleController {
    @Autowired
    private ArticleRepository articleRepository;

    @GetMapping("/articles/new")
    public String newArticleForm() {
        return "articles/new";
    }

    @PostMapping("/articles/create")
    public String createArticle(ArticleForm form) {
        log.info(form.toString());

        // 1. DTO를 entity로 변환하기
        Article article = form.toEntity();
        log.info(article.toString());

        // 2. Repository로 엔티티를 DB에 저장
        Article saved = articleRepository.save(article);
        log.info(saved.toString());
        return "";
    }

    @GetMapping("/articles/{id}")
    public String show(@PathVariable Long id) {
        log.info("id = " + id);

        Article articleEntity = articleRepository.findById(id).orElse(null);
        return "";
    }
}

 

 

2. 가져온 데이터를 모델에 등록하기

데이터를 Model에 등록하는 이유는 MVC 패턴에 따라 조회한 데이터를 View 페이지에서 사용하기 위함

show() 메서드의 매개변수로 model 객체를 받아옴

@GetMapping("/articles/{id}")
public String show(@PathVariable Long id, Model model) {
    log.info("id = " + id);

    Article articleEntity = articleRepository.findById(id).orElse(null);
    return "";
}

 

모델에 데이터를 등록할 때 addAttribute() 메서드 사용

article이라는 이름으로 articleEntity 객체 등록

@GetMapping("/articles/{id}")
public String show(@PathVariable Long id, Model model) {
    log.info("id = " + id);
    Article articleEntity = articleRepository.findById(id).orElse(null);

    model.addAttribute("article", articleEntity);
    return "";
}

 

3. 조회한 데이터를 사용자에게 보여 주기 위한 View 페이지 만들고 반환하기

articles 디렉터리안에 show라는 파일이 있다고 가정한 뒤 생성

@GetMapping("/articles/{id}")
public String show(@PathVariable Long id, Model model) {
    log.info("id = " + id);
    Article articleEntity = articleRepository.findById(id).orElse(null);

    model.addAttribute("article", articleEntity);
    return "articles/show";
}

 

show.mustache 파일 생성

resources>templates>articles에서 show.mustache 생성

layouts 적용

부트스트랩 table 검색 후 복사 붙여넣기

{{>layouts/header}}

<table class="table">
    <thead>
    <tr>
        <th scope="col">#</th>
        <th scope="col">First</th>
        <th scope="col">Last</th>
        <th scope="col">Handle</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <th scope="row">1</th>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
    </tr>
    <tr>
        <th scope="row">2</th>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
    </tr>
    <tr>
        <th scope="row">3</th>
        <td colspan="2">Larry the Bird</td>
        <td>@twitter</td>
    </tr>
    </tbody>
</table>

{{>layouts/footer}}

 

서버 실행

 

표 수정 후 빌드(망치 아이콘)

임시로 넣은 가짜 데이터가 잘 출력됨

{{>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 scope="row">1</th>
        <td colspan="1">제목qwer</td>
        <td>내용1111</td>
    </tr>
    </tbody>
</table>

{{>layouts/footer}}

 

model에서 article이라는 이름으로 articleEntity를 등록함

이때 article은 mustache 문법으로 이중 중괄호({{}})를 이용해 출력한다

{{#article}}{{/article}}과 같이 샵(#)을 이용해 열고 슬래시(/)를 이용해 닫는다

이렇게 가져온 데이터를 여러 행에 걸쳐 사용할 땐 범위를 정해야 한다

범위를 지정했으면 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 scope="row">{{id}}</th>
        <td colspan="1">{{title}}</td>
        <td>{{content}}</td>
    </tr>
    {{/article}}
    </tbody>
</table>

{{>layouts/footer}}

 

서버를 재시작하고 localhost:8080/articles/3에 접속하면 아무것도 조회되지 않는다

이유는 서버를 재시작하여 데이터가 날아갔기 때문이다

localhost:8080/articles/new에 접속하여 제목(점심은), 내용(국수)를 입력한다

 

다시 웹 브라우저에서 localhost:8080/articles/1에 접속해도 에러가 발생한다

No default constructor for entity: : com.example.firstproject.entity.Article

에러 메시지 발생

Article 엔티티에 기본 생성자가 없어서 에러가 발생하였다

 

 

기본 생성자 추가

entity>Article 파일 열기

이전에 lombok으로 생성자 대신 @AllArgsConstructor 어노테이션을 작성하였다

기본 생성자 추가하기

package com.example.firstproject.entity;

import lombok.AllArgsConstructor;
import lombok.ToString;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;


@AllArgsConstructor
@ToString
@Entity
public class Article {
    @Id
    @GeneratedValue
    private Long id;
    @Column
    private String title;
    @Column
    private String content;
    
    // 기본 생성자 추가
    Article() {
        
    } 
}

 

하지만 기본 생성자를 추가하지말고 @NoArgsConstructor 어노테이션을 추가하면 기본 생성자 코드를 작성하지 않아도 된다

@NoArgsConstructor: 기본생성자를 추가해주는 어노테이션

package com.example.firstproject.entity;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.ToString;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;


@AllArgsConstructor
@NoArgsConstructor
@ToString
@Entity
public class Article {
    @Id
    @GeneratedValue
    private Long id;
    @Column
    private String title;
    @Column
    private String content;

}

 

서버 재시작

localhost:8080/articles/new 에서 제목(점심은) 내용(국수)를 입력한 후

localhost:8080/articles/1에 접속하면 입력한 데이터가 잘 나온다

'Spring > 게시판 만들기' 카테고리의 다른 글

link와 redirect를 이용해 페이지 연결  (0) 2023.09.12
데이터 목록 조회하기  (0) 2023.09.12
Lombok  (0) 2023.09.12
데이터 조회  (0) 2023.09.11
H2 DB 접속하기  (0) 2023.09.11