안녕하세요! 오늘은 스프링 부트를 사용하여 블로그의 백엔드 개발을 하는 방법에 대해 자세히 알아보겠습니다. 이 강좌에서는 블로그의 기본적인 화면 구성을 위한 예제를 다룰 예정이며, 실습을 통해 스프링 부트와 타임리프를 활용하는 방법을 함께 배우겠습니다.
강좌 목표
- 스프링 부트의 기본 구조 이해
- 타임리프를 사용하여 동적인 웹 페이지 구성
- 블로그의 기본적인 CRUD 기능 구현
- API 설계 및 데이터베이스 연동 기초 배우기
사전 지식: 타임리프
타임리프(Thymeleaf)는 자바에서 웹 애플리케이션의 뷰를 작성하기 위한 템플릿 엔진입니다. HTML을 기반으로 하며, JSP와 비슷한 역할을 수행하지만, 더 많은 기능과 유연성을 제공합니다. 타임리프의 장점 중 일부는 다음과 같습니다:
- 자연스러운 템플릿: 작성한 템플릿이 일반 HTML 파일로도 유효하다는 점.
- 다양한 뷰 옵션: HTML, XML, JavaScript, CSS 등 다양한 뷰를 지원.
- 서버 측 처리 및 클라이언트 측 처리 모두 가능.
스프링 부트 프로젝트 설정하기
먼저, 스프링 부트 프로젝트를 설정하는 방법을 알아보겠습니다. IntelliJ IDEA 또는 Spring Initializr를 사용하여 새 프로젝트를 생성할 수 있습니다.
1. Spring Initializr 접속: https://start.spring.io/
2. Project: Gradle Project 선택
3. Language: Java 선택
4. Spring Boot: 2.5.4 이상의 버전 선택
5. Project Metadata 입력:
- Group: com.example
- Artifact: blog
6. Dependencies 추가:
- Spring Web
- Spring Data JPA
- H2 Database
- Thymeleaf
7. Generate 클릭하여 프로젝트 다운로드
프로젝트 구조
프로젝트를 생성하면 기본적인 파일 구조가 생성됩니다. 이 구조를 이해하는 것이 중요합니다.
src/main/java
: 자바 소스 코드가 위치하는 폴더입니다.src/main/resources
: 정적 리소스 및 템플릿 파일이 위치하며, application.properties 파일이 포함되어 있습니다.src/test/java
: 테스트 코드가 위치하는 폴더입니다.
블로그 모델 설정
이번 블로그 애플리케이션에서는 기본적으로 포스트(Post) 모델을 설정하겠습니다. 다음과 같은 단계를 통해 포스트 모델을 정의합니다.
package com.example.blog.model;
import javax.persistence.*;
@Entity
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String content;
// 생성자, 게터, 세터
public Post() {}
public Post(String title, String content) {
this.title = title;
this.content = content;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
데이터베이스 설정
H2 데이터베이스를 사용하여 간단하게 데이터를 저장할 수 있습니다. application.properties
파일에서 데이터베이스 설정을 다음과 같이 합니다.
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
레포지토리 인터페이스 생성
JPA를 사용하여 데이터베이스와의 상호작용을 쉽게 하기 위해 Repository 인터페이스를 생성합니다.
package com.example.blog.repository;
import com.example.blog.model.Post;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PostRepository extends JpaRepository {
}
서비스 클래스 생성
서비스 클래스는 비즈니스 로직을 처리하는 곳입니다. 포스트에 대한 CRUD 기능을 포함시킵니다.
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 {
@Autowired
private PostRepository postRepository;
public List findAll() {
return postRepository.findAll();
}
public Post findById(Long id) {
return postRepository.findById(id).orElse(null);
}
public Post save(Post post) {
return postRepository.save(post);
}
public void deleteById(Long id) {
postRepository.deleteById(id);
}
}
컨트롤러 클래스 생성
스프링 MVC의 컨트롤러를 통해 웹 요청을 처리합니다. 포스트의 목록을 반환하고, 포스트를 추가하는 메소드 등을 포함합니다.
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.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class PostController {
@Autowired
private PostService postService;
@GetMapping("/")
public String listPosts(Model model) {
model.addAttribute("posts", postService.findAll());
return "post/list";
}
@GetMapping("/post/new")
public String createPostForm(Model model) {
model.addAttribute("post", new Post());
return "post/create";
}
@PostMapping("/post")
public String savePost(@ModelAttribute Post post) {
postService.save(post);
return "redirect:/";
}
}
타임리프 템플릿 생성
마지막으로, 블로그의 화면을 구성하기 위해 타임리프 템플릿 파일을 생성하겠습니다. 기본 HTML 파일을 작성하고 데이터를 출력하는 방법을 살펴보겠습니다.
포스트 목록 화면
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>블로그 포스트 목록</title>
</head>
<body>
<h1>블로그 포스트</h1>
<a href="@{/post/new}">새 포스트 추가</a>
<ul>
<li th:each="post : ${posts}">
<a th:href="@{/post/{id}(id=${post.id})}">
<span th:text="${post.title}"></span></a>
</li>
</ul>
</body>
</html>
포스트 작성 화면
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>새 포스트 작성</title>
</head>
<body>
<h1>새 포스트 작성</h1>
<form action="#" th:action="@{/post}" th:object="${post}" method="post">
<label for="title">제목:</label>
<input type="text" id="title" th:field="*{title}" required/>
<br/>
<label for="content">내용:</label>
<textarea id="content" th:field="*{content}" required></textarea>
<br/>
<button type="submit">작성하기</button>
</form>
<a href="@{/}">목록으로 돌아가기</a>
</body>
</html>
결론
이번 강좌에서는 스프링 부트를 이용한 백엔드 개발과 타임리프를 활용한 간단한 블로그 화면 구성을 살펴보았습니다. 이번 예제를 통해 스프링 부트의 기본적인 작동 방식을 이해하고, 타임리프를 사용하여 동적인 웹 페이지를 만드는 방법을 익힐 수 있었습니다.
더 나아가, 이 예제를 기반으로 다양한 기능을 추가하거나, 다른 디자인 패턴을 적용해보세요. 스프링 부트와 타임리프를 사용하여 실제 애플리케이션을 개발하는 과정에서 많은 것을 배우게 될 것입니다.
감사합니다!