스프링 부트(Spring Boot)로 간단한 게시판 만들기 - 2

2022. 8. 2. 16:50How to become a real programmer

이전 단계를 따라했다면, 프로젝트 생성을 할 차례이다.

2) 프로젝트 생성

 - IntelliJ Community에서 Spring Boot 프로젝트 생성

 

아래 스프링 부트 시작사이트에서 설정을 거친 후 프로젝트 생성이 가능하다.

https://start.spring.io/

그리고 설정을 위와 같이 해준다. 체크표시 한 부분을 수정해주고, Dependencies는 의존성 설정하는 부분인데, 5가지를 추가해주면 된다.

우선 Project 부분에서 Maven과 Gradle 두 가지는 프로젝트 라이프사이클을 관리하는 도구이다. 둘 중 하나를 설정해주면 되고, 스프링부트 버전은 Snapshot, M이 보이며 각 버전 차이는 아직 확실히 와닿지 않는다. 이번 프로젝트를 하고나면 이해가 되려나. 

 - Snapshot : 아직 개발중인 버전으로, 언제든지 기능이 추가되고 삭제될 수 있는 가장 불안정한 버전

 - M(Milestone build) : 완전하지 않은 기능이 포함된 버전, Snapshot보단 안정적이지만 여전히 문제가능, 기능이 완성되자마자 공개되는 편

 

어쨋든, Generate를 누르면 zip파일 하나가 받아지는데 해당 파일을 이전에 생성해놓은 프로젝트 폴더에 압축해제해준다. 

IntelliJ에서 해당폴더를 Open Folder해주면 해당 폴더가 열리는데, 아래와 같은 창을 볼 수 있을 것이다.

해당 창에서, src - main - java - com.study.board - BoardApplication.java 파일을 열어보자

여기서 상단 왼쪽의 intelliJ의 settings(mac의 경우 preference)에 들어가서 gradle을 검색하여 아래와 같이 두 부분을 IntelliJ로 설정해준다.

그리고 오른쪽 상단 실행버튼을 눌러보면 아래와 같은 결과가 나온다.

그리고 이후, src - main - resources - application.properties에 들어가 아래와 같이 설정해준다.

프로젝트와 데이터베이스를 연결하는 과정이라고 보면 되겠다. 패스워드 부분은 본인이 설정한 mariaDB의 패스워드를 입력하면 된다.

그리고 이전에 생성한 스키마인 board를 localhost:3306/board로 할당해주면 된다.  

이후 오른쪽 상단 run 버튼을 눌렀더니 위 처럼 ... Started BoardApplication in .,,, 이라고 뜨는것을 보니 정상적으로 실행된 것이다.

그리고 크롬에 접속하여 localhost:8080으로 접속해서 아래와 같이 오류창이 뜨면 연결이 된 것이다.

이제 이 창에 간단한 수정을 거쳐보자.

com.study.board 패키지 내에 controller 패키지를 생성, 내부에 BoardController 자바 클래스 파일을 만들어주자.

내부 내용은 아래와 같다

package com.study.board.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class BoardController {

    @GetMapping("/")
    @ResponseBody

    public String main() {
        return "Hello World";
    }
}

@Controller 임을 알려주고, @GetMapping은 주소와 매핑해주는 것이다. localhost:8080/ 이므로, 그냥 "/"만 하면 아까 들어갔던 창에 매핑을 해준다는 뜻이다.

@ResponseBody는 해당 페이지에 아래 내용을 출력한다는 것이고 return "Hello World"를 해주면 아마 페이지에 "Hello World"를 리턴할 것이다.

Run을 다시 해준 후 아까 페이지에서 새로고침 해주면, 아래와 같이 잘 출력되는 것을 확인가능하다.

 

 

3) 게시물 작성

 - MariaDB Database에 'Board' 테이블 생성

테이블은 틀이라고 생각하면 될 것 같다. 데이터베이스 - 스키마 - 테이블 처럼 하위단계로 연결되어 있으며 테이블이 있어야 틀에 맞게 데이터를 저장하여 관리할 수 있다. 

테이블 생성을 위해 MySQL Workbench를 실행해주고, 이전에 생성해둔 board 스키마에서 테이블을 오른쪽 클릭, create table해주자

 그러고 나면, 아래와 같은 창이 뜰 것이다.

여기서 column으로 id, title, content를 추가해준다.

id는 데이터베이스 내 데이터의 고유 넘버라고 생각하면 되고 그렇기에 Primary KEY - 식별할 수 있는 고유키 이다. 데이터베이스 내 데이터들의 차별점이 되는 KEY라고 생각하면 되겠다. 그렇기에 1부터 +1씩 계속 할당해주기 위해 Auto Increment인 AI를 체크, title과 content는 설정에서 content는 들어갈 문자 양이 많을 수 있으므로 text로 데이터타입을 설정해주고 세가지 모두 다 NotNULL에 체크해주자.(공백불가라는 뜻) 그리고 Appliy해주면 table내 column 생성까지 완료된 것이다. 

 

 - 게시물 작성 폼 생성

작성 폼을 만들어주기 위해 IntelliJ로 편집해야한다. IntelliJ에서, resources - templates 내부에 boardwrite라는 이름의 HTML파일을 하나 추가하자.

HTML파일 내부에 아래와 같은 내용을 추가해준다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>게시물 작성폼</title>
</head>
<body>
<div class="layout">
    <input type="text">
    <textarea></textarea>
    <button>작성</button>
</div>

</body>
</html>

그냥 기존 HTML 양식에서 title변경 해주고 text 타입의 input과 textarea, button을 추가해준 것이다. 그리고 해당HTML파일을 localhost경로에 할당해주어야 하기 때문에 BoardController 파일로 가 수정해야한다.

내용을 위와같이 추가해준다. @GetMapping은 아까 설명했던 것 같이 아래 method를 url 경로에 매핑해주는 것이기 때문에 우린 아까 만든 HTML을 localhost:8080/board/write에 할당하기 위해 @GetMapping("/board/write") 해준다.

그리고 아래 boardWriteForm 메소드는 boardwrite.html을 return해주기 위해 위와같이 작성해준다. 그리고 run.

run이 되었으면 아까 설정한 localhost:8080/board/write에 접속해본다.

 

아까 만들어 둔 input, textarea, button이 만들어 진 것을 확인할 수 있다.

저렇게 생긴 게시물 등록은 너무 심하다 생각해서 살짝만 고쳐줬다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>게시물 작성폼</title>
</head>
<style>
    </style>
<body>
<div class="layout">
    <div class="mb-3">
        <label for="exampleFormControlInput1" class="form-label">Name</label>
        <input type="text" id="exampleFormControlInput1" placeholder="Your Name">
    </div>
    <br>
    <div class="mb-3">
        <label for="exampleFormControlTextarea1" class="form-label">Example textarea</label><br>
        <textarea id="exampleFormControlTextarea1" rows="5">Write Something</textarea>
    </div>
    <button type="submit">작성</button>
</div>
</body>
</html>

이것도 많이 별로지만 아까보단 좀 낫다.. ㅋㅋ;

 

 - 게시물 작성 처리

이제 해당 폼에 이름과 내용을 넣고 제출될 수 있게 작동해야한다.

그러기 위해서 아까 작성한 text와 textarea내 내용들이 POST방식을 통해서 보내지도록 하겠다. 우선 두 내용을 form으로 감싸고, 작성한 해당 내용들이 보내질 경로(action)과 보내지는 방식(method)를 지정해준다. 그리고 text의 name으로 title을 추가해주고, textarea의 name으로 content를 추가해주자. 그리고 button은 type으로 submit을 가져야 해당 버튼이 눌리면 form내부 내용들이 옮겨진다.

name을 설정하는 이유는 해당 폼 안에 작성한 텍스트(데이터)들이 name이름과 동일한 변수로 옮겨지므로 설정해주는 것이다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>게시물 작성폼</title>
</head>
<style>
    </style>
<body>
<div class="layout">
    <form action="/board/writedo" method="post">
        <div class="mb-3">
            <label for="exampleFormControlInput1" class="form-label">Name</label>
            <input type="text" name="title" id="exampleFormControlInput1" placeholder="Your Name">
        </div>
        <br>
        <div class="mb-3">
            <label for="exampleFormControlTextarea1" class="form-label">Example textarea</label><br>
            <textarea id="exampleFormControlTextarea1" name="content" rows="5">Write Something</textarea>
        </div>
        <button type="submit">작성</button>
    </form>
</div>
</body>
</html>

위와같이 될것이다.

그리고 re run해준 후, 페이지에서 아무 내용이나 넣고 submit하면?

당연히 action 경로인 /board/writedo에 아무런 내용이 없기에 404에러가 뜰 것이다.

일단 해당 페이지 내용을 작성해주기 전에, 제대로 POST를 통해 데이터가 도착하는지를 간단히 확인해보자.

BoardCintroller 자바 클래스파일에 아래와 같이 PostMapping 해주면 그쪽으로 이동하는 데이터를 확인할 수 있는데 아래와 같이 println을 통해서 콘솔창에서 받아온 내용을 확인 해 줄것이다.

write 페이지에서,

이렇게 작성 후 작성버튼을 누르면!

콘솔창에 해당 내용이 잘 나타난다.

이를 DB에 저장하기 위해선 레포지토리라는 것이 필요한데, 그 전에 패키지를 몇개 만들어주자.

com.study.board 하위에 repositoty, entity라는 이름의 패키지를 생성해주자.

 

그리고 entity 패키지 내에 board라는 이름의 java 클래스 파일를 하나 만들어 준다.

그리고 파일 내용에 @Entity를 추가해준다.

package com.study.board.entity;

import javax.persistence.Entity;

@Entity
public class Board {
}

Entity는 테이블을 의미한다. 클래스 명이 db에 있는 테이블을 의미한다는 것이다. Board 내에

	private Integer id;

    private String title;

    private String content;

로 테이블 내에 column들 이름을 하나씩 작성해준다.

그리고 아래와 같이 @Data(변수로 Id, title, content를 받을 수 있게 해준다), @Id, @GeneratedValue를 추가해준다.

package com.study.board.entity;

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

@Entity
@Data
public class Board {
    @Id // primary key를 의미
    @GeneratedValue(strategy = GenerationType.IDENTITY) // strategy를 GenerationType.IDENTITY로 해준다(MySQL, MariaDB / SEQUENCE는 오라클 용 / AUTO는 자동지정)
    private Integer id;

    private String title;

    private String content;
}

그리고 BoardController.java에서 아래와 같이 수정을 거친다.

package com.study.board.controller;

import com.study.board.entity.Board;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class BoardController {
    @GetMapping("/board/write") //localhost:8080/board/write
    public String boardWriteForm() {
        return "boardwrite";
    }
    @PostMapping("/board/writedo")
    public String boardWritePro(Board board) {

        System.out.println(board.getTitle());
        return "";
    }
}

Entity 폴더 내에 class 파일을 생성한 것은, 해당 클래스 명을 자료형으로 사용할 수 있도록 해주기 위해서이다. @Data를 통해서 Board자료형의 변수 board의 title을 가져올 수 있는 board.getTitle()을 사용할 수 있게 되어서 해당 내용을 콘솔창에서 확인해보도록 코드를 작성했다. 한번 re run하고, 다시 폼을 submit해 title내용이 잘 콘솔창에 나오는지 확인해보겠다.

title에 '하이하이'를 작성하고 submit하니 아래와 같이 콘솔창에 잘 나타남을 확인할 수 있었다.

Entity로 설정한 자료형으로도 잘 받을 수 있는것을 알았으니 DB에 저장할 수 있도록 repository 부분을 추가해보자.

repository에 BoardRepository라는 이름의 Interface를 추가해주자.

두 번째 인터페이스를 눌러줘야 한다

그리고 해당 인터페이스에 @Repository를 추가해 레포지토리라고 지정을 해준다. 그리고 JPARepository를 상속하고 <>사이에 board의 타입과 Id를 사용한다고 작성해줘야하기에. 각각 Board, Integer을 넣어준다(자료형 넣는 부분이라 변수명이 아닌 자료형 이름을 넣어줘야한다). 아래와 같이 작성할 수 있겠다.

package com.study.board.repository;

import com.study.board.entity.Board;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface BoardRepository extends JpaRepository<Board, Integer> {
}

그리고 com.study.board 패키지 하위에 Service 패키지를 추가해주자. 그리고 Service패키지 하위에 BoardService라는 이름의 java 클래스 파일을 생성, 후 @Service를 추가해 서비스 파일이라는 것을 지정해준다.

-BoardService.class 내용(아래)-

package com.study.board.service;

import com.study.board.entity.Board;
import com.study.board.repository.BoardRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BoardService {
    @Autowired
    private BoardRepository boardRepository; // 객체를 생성 - 스프링 부트에서 제공하는 Autowired를 사용하면 스프링이 알아서 읽어와서 자동으로 주입을 해준다 dependency injection(의존성 주입)이라 함

    public void write(Board board){
        boardRepository.save(board); // 이렇게 생성한 서비스는 다시 컨트롤러에서 사용할 것
    }
}

@Service라는 것을 지정해주고, 내부에 BoardRepository 인터페이스를 선언해준다. Autowired라는 스프링부트에서 제공하는 어노테이션(@)을 사용하면 boardRepository = new board,,,이렇게 객체생성을 해줄 필요없이 사용가능하다. 이를 의존성 주입이라고 한다.

그리고 write 메소드에서 Board 타입의 board를 매개변수로 받아와 boardRepository.save의 변수로 준다. 

정확한 처리과정은 컨트롤러 작성까지 마친 후 설명하겠다.

BoardController 파일에서, 아래와 같이 수정하였다.

아까 생성한 BoardService파일을 가져와 Autowired를 통해 선언하고, 아래에서 boardService에서 만들었던 write메서드를 사용한다.

그리고 일단 run해보자.

들어온 데이터를 확인하는 방법을 우선 말하자면 workbench에서 아래에서 빨간박스로 표시한 부분을 누르면 데이터베이스 내에 저장된 내용을 확인가능하다.

페이지에 들어가 내용을 넣어주고 submit해주자.

 그리고 데이터베이스 내부를 확인하면,

위와같이 title과 content column에 맞춰 데이터가 잘 들어온것을 확인가능하다.

새로고침 버튼은 동그라미 부분을 누르면 조회가 가능하다.

 

이후 부분인

4) 게시물 리스팅

 - 게시물 리스트 페이지 생성

 - 게시물 리스트 페이지에 저장된 게시글 출력

 

5) 게시물 삭제

 - 게시물 삭제 버튼 생성

 - 게시물 삭제 처리

는 다음 글에서 계속 설명하도록 하겠다.

 

----------------------------------------------------------------------------------------------------------------------

간단히,

BoardController.java - 매핑 하는 역할

 

폼 생성

boardwrite.html - templates / 웹 페이지

Board.java - Entity / 데이터베이스 table형식

BoardRepository.interface - 자료형 같은 느낌