스프링 부트 백엔드 개발 강좌, 블로그 화면 구성 예제, 타임리프 문법 익히기용 컨트롤러 작성하기

1. 개요

이 강좌에서는 스프링 부트를 이용한 백엔드 개발을 위한 기본적인 이해를 돕고, 블로그 화면 구성 예제를 통해 타임리프 문법을 익히는 방법을 설명합니다.

스프링 부트(Spring Boot)는 자바 기반의 웹 어플리케이션 프레임워크로, 복잡한 설정 없이 빠르고 간편하게 웹 애플리케이션을 만들 수 있도록 도와줍니다. 이를 통해 개발자는 비즈니스 로직에 집중하며, 생산성을 높일 수 있습니다.

2. 기술 스택

이번 강좌에서 사용할 주요 기술 스택은 다음과 같습니다:

  • Java 11 이상
  • Spring Boot 2.x
  • Thymeleaf
  • Spring Data JPA
  • H2 Database

이 기술 스택은 백엔드 개발에 있어 강력한 조합을 이룹니다. 각 기술 스택의 간략한 설명은 다음과 같습니다.

  • Java: 객체 지향 프로그래밍 언어로, 플랫폼에 독립적입니다.
  • Spring Boot: Java Spring에서 설정과 배포를 간소화한 프레임워크입니다.
  • Thymeleaf: HTML5 템플릿 엔진으로, 뷰를 구성하는 데 사용됩니다.
  • Spring Data JPA: 데이터베이스와의 상호작용을 쉽게 도와주는 라이브러리입니다.
  • H2 Database: 메모리 기반의 경량형 데이터베이스로, 테스트와 프로토타입에 적합합니다.

3. 프로젝트 설정

스프링 부트 프로젝트를 설정하기 위해 Spring Initializr를 사용합니다. Spring Initializr에 접속하여 아래의 설정을 합니다:

  • Project: Maven Project
  • Language: Java
  • Spring Boot: 2.x
  • Group: com.example
  • Artifact: blog
  • Dependencies: Spring Web, Thymeleaf, Spring Data JPA, H2 Database

위의 설정을 저장하고, 프로젝트를 내려받습니다. 이후 IDE에서 임포트하여 작업을 시작합니다.

4. 엔티티 클래스 생성

애플리케이션에 필요한 데이터 모델을 정의하기 위해 엔티티 클래스를 생성합니다. 기본적인 블로그 게시물을 저장하기 위해 Post 엔티티 클래스를 아래와 같이 작성합니다:

package com.example.blog.model;

import javax.persistence.*;

@Entity
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String title;

    @Column(nullable = false)
    private String content;

    private String author;

    // getters and setters
}

이 클래스는 게시물의 ID, 제목, 내용 및 작성자를 포함하고 있습니다. JPA를 활용하여 데이터베이스와의 매핑을 처리합니다.

5. 레포지토리 인터페이스 생성

Post 엔티티에 대한 CRUD 작업을 처리하기 위해 JpaRepository를 상속받는 레포지토리 인터페이스를 생성합니다:

package com.example.blog.repository;

import com.example.blog.model.Post;
import org.springframework.data.jpa.repository.JpaRepository;

public interface PostRepository extends JpaRepository {
}

이 인터페이스는 Post 엔티티와 연결된 데이터베이스의 CRUD 작업을 간편하게 사용할 수 있도록 해줍니다.

6. 서비스 클래스 작성

비즈니스 로직을 담당하는 서비스 클래스를 생성하여 비즈니스 규칙을 정의합니다. PostService 클래스를 아래와 같이 작성합니다:

package com.example.blog.service;

import com.example.blog.model.Post;
import com.example.blog.repository.PostRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class PostService {
    private final PostRepository postRepository;

    @Autowired
    public PostService(PostRepository postRepository) {
        this.postRepository = postRepository;
    }

    public List findAll() {
        return postRepository.findAll();
    }

    public Post save(Post post) {
        return postRepository.save(post);
    }

    public Post findById(Long id) {
        return postRepository.findById(id).orElse(null);
    }

    public void deleteById(Long id) {
        postRepository.deleteById(id);
    }
}

이 클래스는 게시물 목록을 조회하고, 게시물을 저장 및 삭제하는 메소드를 정의하고 있습니다.

7. 컨트롤러 작성

이제 클라이언트 요청을 처리하기 위해 컨트롤러 클래스를 작성합니다. PostController 클래스를 아래와 같이 작성할 수 있습니다:

package com.example.blog.controller;

import com.example.blog.model.Post;
import com.example.blog.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Controller
@RequestMapping("/posts")
public class PostController {
    private final PostService postService;

    @Autowired
    public PostController(PostService postService) {
        this.postService = postService;
    }

    @GetMapping
    public String list(Model model) {
        List posts = postService.findAll();
        model.addAttribute("posts", posts);
        return "post/list";
    }

    @GetMapping("/new")
    public String createForm(Model model) {
        model.addAttribute("post", new Post());
        return "post/form";
    }

    @PostMapping
    public String create(Post post) {
        postService.save(post);
        return "redirect:/posts";
    }
    
    @GetMapping("/{id}")
    public String view(@PathVariable Long id, Model model) {
        Post post = postService.findById(id);
        model.addAttribute("post", post);
        return "post/view";
    }

    @GetMapping("/edit/{id}")
    public String editForm(@PathVariable Long id, Model model) {
        Post post = postService.findById(id);
        model.addAttribute("post", post);
        return "post/form";
    }

    @PostMapping("/edit/{id}")
    public String edit(@PathVariable Long id, Post post) {
        post.setId(id);
        postService.save(post);
        return "redirect:/posts";
    }

    @GetMapping("/delete/{id}")
    public String delete(@PathVariable Long id) {
        postService.deleteById(id);
        return "redirect:/posts";
    }
}

컨트롤러는 패턴에 따라 HTTP 요청에 대한 핸들러 메소드들을 정의합니다. 위 코드에서는 게시물의 목록, 게시물 생성, 수정, 삭제 기능을 구현합니다.

8. 타임리프 템플릿 작성

이제 Thymeleaf를 사용하여 HTML 뷰를 작성할 시간입니다. 게시물 목록을 표시할 list.html은 다음과 같이 작성할 수 있습니다:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>게시물 목록</title>
</head>
<body>
    <h1>게시물 목록</h1>
    <a href="@{/posts/new}">새 게시물 작성</a>
    <ul>
        <li th:each="post : ${posts}">
            <a th:href="@{/posts/{id}(id=${post.id})}">[[${post.title}]]</a>
        </li>
    </ul>
</body>
</html>

위 템플릿은 게시물 목록을 표시하며, 각 게시물 제목을 클릭하면 해당 게시물의 세부 정보 페이지로 이동합니다.

9. 마무리

이 강좌에서는 스프링 부트와 타임리프를 사용하여 간단한 블로그 애플리케이션을 구축하는 방법을 소개했습니다. 각 단계별로 엔티티, 레포지토리, 서비스, 컨트롤러 및 뷰를 만들어가며 기초적인 백엔드 개발을 이해하는 데 도움이 되었길 바랍니다.

더 많은 기능을 추가하고 싶다면, 게시물의 댓글 기능, 사용자 인증 및 권한 관리 등을 구현해 보세요. 이를 통해 더 발전된 웹 애플리케이션 개발의 기초를 쌓을 수 있을 것입니다.