본문 바로가기

프로그래밍/스프링부트(springboot)

[스프링부트/springboot] 스프링 부트 JPA로 CRUD 해보기

저번꺼에 이어서 진행하도록 하겠습니다.

 

buildscript {
    ext {
        // 스프링 부트 버전
        springBootVersion = "2.2.0.RELEASE"
    }
    repositories {
        mavenCentral()
        maven { url "https://plugins.gradle.org/m2/" } // plugin 저장소
    }
    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
    }
}

plugins {
    id 'org.springframework.boot' version '2.2.0.RELEASE'
    id 'io.spring.dependency-management' version '1.0.10.RELEASE'
    id 'java'
}

jar {
    baseName = 'demo'
    version = '0.0.1-SNAPSHOT'
}

group 'com.example.spring'
version '0.0.1-SNAPSHOT'

sourceCompatibility = 11
targetCompatibility = 11

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.mariadb.jdbc:mariadb-java-client'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

    compileOnly ('org.projectlombok:lombok')
    annotationProcessor ('org.projectlombok:lombok')

    runtimeOnly ('org.springframework.boot:spring-boot-devtools')
    runtimeOnly ('org.mariadb.jdbc:mariadb-java-client')

    testCompile ('org.springframework.boot:spring-boot-starter-test')
}

 

build.gradle 는 지난번 시간과 다르지 않게 설정되었습니다.

 

 

 

    @Test
    public void 상세조회_테스트() {
        Board board = boardRepo.findById(1L).get();
        System.out.println(board.toString());
    }

 

CrudRepository의 상속을 받은 boardRepo에 기본으로 findById 을 사용할 수 있는데, 앞에 find는 select를 뜻하고, By 뒤에 ID는 Board 에서 만들어둔 @ID를 조건으로 사용하여 조회합니다.

 

 

test를 실행해 보면 Hibernate가 위와 같이 진행되었음을 알 수 있습니다.

 

 

 

    @Test
    public void 수정기능_테스트() {
        System.out.println("=== 1번 게시글 조회 ===");
        Board board = boardRepo.findById(1L).get();

        System.out.println("=== 1번 게시글 제목 수정 ===");
        board.setTitle("제목을 수정했습니다.");
        boardRepo.save(board);
    }

 

 

 

위에는 콘솔창에 출력된 Hibernate의 일부분입니다.

업데이트를 진행하기 위해서는 Board 테이블에 id 가 있어야 하고 save시, id를 제외한 컬럼을 넣습니다.

 

 

 

    @Test
    public void 삭제기능_테스트() {
        boardRepo.deleteById(1L);
    }
    

 

 

 

JPA에서 delete를 진행하기 위해서는 delete가 붙은 메서드를 사용하며, 먼저 테이블에 입력한 id가 있는지 찾은 후 delete SQL를 실행하게 됩니다.

 

 

 

DB 내용을 보면 지워진것을 알 수 있습니다.

 

이제, thymeleaf 템플릿을 이용하여, 게시판의 CRUD를 진행해 보겠습니다.

 

먼저 java단부터 새로 작성을 하겠습니다.

 

 

크게 controller 단, service 단 으로 두개를 추가로 만들어 보겠습니다.

 

먼저 BoardService.java의 소스코드입니다.

 

package blog.dev.example.service;

import blog.dev.example.domain.Board;

import java.util.List;

public interface BoardService {

    public List<Board> getBoardList(Board board);
    public void insertBoard(Board board);
    public Board getBoard(Long seq);
    public void updateBoard(Board board);
    public void deleteBoard(Board board);

}

 

BoardServiceImpl.java의 소스입니다.

 

package blog.dev.example.service;

import blog.dev.example.domain.Board;
import blog.dev.example.repository.BoardRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BoardServiceImpl implements BoardService {

    @Autowired
    private BoardRepository boardRepo;

    /**
     * board 내용을 조회합니다.
     *
     * @param board
     * @return
     */
    public List<Board> getBoardList(Board board) {
        return (List<Board>) boardRepo.findAll();
    }

    /**
     * board 내용을 입력한다.
     *
     * @param board
     */
    public void insertBoard(Board board) {
        boardRepo.save(board);
    }

    /**
     * board 상세 내용을 조회한다.
     *
     * @param seq
     * @return
     */
    public Board getBoard(Long seq) {
        return boardRepo.findById(seq).get();
    }

    /**
     * board 내용을 수정한다.
     *
     * @param board
     */
    public void updateBoard(Board board) {
        Board findBoard = boardRepo.findById(board.getSeq()).get();

        findBoard.setTitle(board.getTitle());
        findBoard.setContent(board.getContent());
        boardRepo.save(findBoard);
    }

    /**
     * board 내용을 삭제한다.
     *
     * @param board
     */
    public void deleteBoard(Board board) {
        boardRepo.deleteById(board.getSeq());
    }

}

 

controllerr 단 소스입니다.

 

package blog.dev.example.controller;

import blog.dev.example.domain.Board;
import blog.dev.example.service.BoardServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;

@Controller
public class BoardController {

    @Autowired
    private BoardServiceImpl boardService;

    @RequestMapping("/")
    public String getBoardList(Model model, Board board) {
        List<Board> boardList = boardService.getBoardList(board);

        model.addAttribute("boardList", boardList);
        return "BoardList";
    }

    @RequestMapping(value = "/insertBoard", method = RequestMethod.GET)
    public String insertBoardView(Model model) {
        Board board = new Board();

        model.addAttribute("board", board);
        return "insertBoard";
    }

    @RequestMapping(value = "/insertBoard", method = RequestMethod.POST)
    public String insertBoard(Board board) {
        boardService.insertBoard(board);
        return "redirect:/";
    }

    @RequestMapping("/getBoard")
    public String getBoard(Long seq, Model model) {
        model.addAttribute("board", boardService.getBoard(seq));
        return "getBoard";
    }

    @RequestMapping(value = "/updateBoard", method = RequestMethod.POST)
    public String updateBoard(Board board) {
        boardService.updateBoard(board);
        return "forward:/";
    }

}

 

그 다음 화면단을 만들어 보겠습니다.

 

 

 

 

템플릿을 사용하기 때문에 templates 폴더를 resources폴더에 만들어 줍니다.

 

BoardList.html 의 소스코드 입니다.

 

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>게시글 상세</title>
    <link rel='stylesheet' href='/webjars/bootstrap/3.3.7/css/bootstrap.min.css'>
    <script src="/webjars/bootstrap/jquery/1.12.0/jquery.min.js"></script>
</head>
<body style="width: 80%; margin: 0 auto;">

    <div class="panel-body pull-right">
        <h3><a class="label label-default" href="insertBoard">Register</a></h3>
    </div>

    <div class="panel-body">
        <div>
            <table class="table table-striped table-bordered table-hover" id="dataTables-example">
                <thead>
                    <tr>
                        <th>제목</th>
                        <th>작성자</th>
                        <th>내용</th>
                        <th>등록일</th>
                        <th>조회수</th>
                    </tr>
                </thead>
                <tbody>
                    <tr class="odd gradeX" th:each="board:${boardList}">
                        <td><a th:href="@{/getBoard(seq=${board.seq})}">[[${board.title}]]</a></td>
                        <td>[[${board.writer}]]</td>
                        <td>[[${board.content}]]</td>
                        <td>[[${#dates.format(board.createDate, 'yyyy-MM-dd')}]]</td>
                        <td>[[${board.cnt}]]</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>

</body>

 

getBoard.html 소스코드입니다.

 

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>등록</title>
    <link rel='stylesheet' href='/webjars/bootstrap/3.3.7/css/bootstrap.min.css'>
    <script src="/webjars/bootstrap/jquery/1.12.0/jquery.min.js"></script>
</head>
<body>
<div class="panel-body">
    <form action="/updateBoard" method="post">

        <div clas="form-group">
            <label>title</label>
            <input class="form-control" name="title" th:value="${board.title}" readonly />
            <p class="help-block">Title text here.</p>
        </div>

        <div class="form-group">
            <label>Content</label>
            <textarea class="form-control" row="3" name="content">[[${board.content}]]</textarea>
        </div>

        <div class="form-group">
            <label>writer</label>
            <input class="form-control" name="writer" th:value="${board.writer}" readonly />
        </div>

        <input type="hidden" name="seq" th:value="${board.seq}" />

        <button type="submit" class="btn btn-default">Modify</button>
        <a href="/"><button class="btn btn-primary">글목록</button></a>

    </form>
</div>
</body>
</html>

 

insertBoard.html 소스 코드입니다.

 

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>등록</title>
    <link rel='stylesheet' href='/webjars/bootstrap/3.3.7/css/bootstrap.min.css'>
    <script src="/webjars/bootstrap/jquery/1.12.0/jquery.min.js"></script>
</head>
<body>
    <div class="panel-body">
        <form action="/insertBoard" method="post">

            <div clas="form-group">
                <label>title</label>
                <input class="form-control" name="title" />
                <p class="help-block">Title text here.</p>
            </div>

            <div class="form-group">
                <label>Content</label>
                <textarea class="form-control" row="3" name="content"></textarea>
            </div>

            <div class="form-group">
                <label>writer</label>
                <input class="form-control" name="writer" />
            </div>

            <button type="submit" class="btn btn-default">Submit</button>
            <button type="reset" class="btn btn-primary">Reset</button>

        </form>
    </div>
</body>
</html>

 

 

그리고 화면단에 제가 부트스트랩과 제이쿼리를 추가해보았는데요.

script에 url로 불러오는 경우도 있겠지만 저는 build.gradle 에 라이브러리르 추가하여 사용하였습니다.

 

 

 // https://mvnrepository.com/artifact/org.webjars/bootstrap
    compile group: 'org.webjars', name: 'bootstrap', version: '3.3.7'
    // https://mvnrepository.com/artifact/org.webjars/jquery
    compile group: 'org.webjars', name: 'jquery', version: '1.12.0'

 

이 두개를 추가해주면 /webjars 로 간단하게 불러올수 있습니다.

 

 

만든 프로젝트를 실행하게 되면 밑에 와 같습니다.

 

 

아직 데이터가 없어서 아무것도 안뜨지만 Register 버튼을 클릭하여 데이터를 추가하여 보겠습니다.

 

 

 

 

그리고 제목의 내용을 누르게 되면 상세페이지, 수정이 가능한 곳으로 이동이 됩니다.