
이전에는 자바 학습에 이어 스프링 부트 1주차 학습 후기를 공유하고자 합니다. 스프링부트까지 학습한후 자바를 이용한 웹서비스를 만들어 볼수 있도록 마지막 4주차 까지 열심히 달려보겠습니다.
1일차 : 스프링 부트 시작하기
스프링 부트의 개념, 개발 환경 설정 방법, 그리고 웹 서비스의 동작 원리에 대해 기본적인 내용들을 학습하였습니다.

- 스프링 부트란?: 스프링 프레임워크를 보다 쉽고 빠르게 개발할 수 있도록 지원하는 도구입니다. 복잡한 설정을 간소화하여 개발에 집중할 수 있게 해준다는 점에서 매우 유용하다고 생각합니다.
- 개발 환경 설정: JDK, IntelliJ IDEA와 같은 통합 개발 환경(IDE) 설정부터 자바 버전 관리까지, 초기 환경 설정까지 스프링 부트 개발에 필요한 것들을 완료했습니다.
- 웹 서비스 동작 원리: 클라이언트-서버, 요청-응답과 같은 웹의 기본적인 흐름을 정리하였습니다.
2일차 : MVC 패턴 이해와 실습
뷰 템플릿과 MVC 패턴의 개념을 익히고, 이를 활용하여 페이지를 직접 구현해 보았습니다.
- 뷰 템플릿과 MVC 패턴: 화면을 담당하는 뷰(View), 데이터를 처리하는 모델(Model), 그리고 이 둘을 연결하는 컨트롤러(Controller)로 역할이 분리되어 코드가 훨씬 구조적이고 이해하기 쉬웠습니다.
- MVC 활용 뷰 템플릿 페이지 만들기: 직접 코드를 작성하여 페이지를 구현해 보니, MVC가 실제로 동작하는 것을 확인하여 이해할 수 있었습니다.
- MVC의 역할과 실행 흐름: 요청이 들어왔을 때 컨트롤러가 이를 받아 모델을 처리하고, 뷰로 전달하는 전체 흐름을 파악하여 웹 개발의 큰 그림을 그릴 수 있었습니다.
- 레이아웃 적용: 페이지에 레이아웃을 적용하여 보다 완성도 높은 형태를 갖출 수 있었습니다.
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<title>Hello, world!</title>
</head>
<body>
<!-- navigation -->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
</nav><!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<title>Hello, world!</title>
</head>
<body>
<!-- navigation -->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
</nav>/layouts/header.mustache
<!-- site info -->
<div class="mb-5 container-fluid">
<hr>
<p>ⓒ CloudString | <a href="#">Privacy</a> | <a href="#">Terms</a></p>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>/layouts/footer.mustache
{{>layouts/header}}
<div class="bg-dark text-white p5">
<h1>{{username}}님, 반갑습니다!</h1>
</div>
{{>layouts/footer}}/greetings.mustache
{{>layouts/header}}
<div class="bg-dark text-white p5">
<h1>{{nickname}}님, 다음에 또 만나요!</h1>
</div>
{{>layouts/footer}}/goodbye.mustache
3일차 : 게시판 만들기: 새 글 작성하기 (Create)
실제 게시판 구현의 첫 단계인 새 글 작성(Create) 기능을 학습하였습니다.
- 폼 데이터란? 웹 페이지에서 사용자로부터 입력받는 데이터를 의미합니다.
- 폼 데이터를 DTO로 받기: DTO(Data Transfer Object)를 사용하여 데이터를 효율적으로 묶어 관리하는 방법을 익혔습니다.
- DTO를 데이터베이스에 저장하기: 작성된 DTO 데이터를 데이터베이스에 저장하는 과정을 실습했습니다.
package com.example.firstproject.dto;
import com.example.firstproject.entity.Article;
public class ArticleForm {
private String title; // 제목을 받을 필드
private String content; // 내용을 받을 필드
// 전송받은 제목과 내용을 필드에 저장하는 생성자 추가
public ArticleForm(String title, String content) {
this.title = title;
this.content = content;
}
// 데이터를 잘 받았는지 확인할 toString() 메서드 추가
@Override
public String toString() {
return "ArticleForm{" +
"title='" + title + '\'' +
", content='" + content + '\'' +
'}';
}
public Article toEntity() {
return new Article(null, title, content);
}
}/dto/ArticleForm
package com.example.firstproject.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
@Entity
public class Article {
@Id
@GeneratedValue
private Long id;
@Column
private String title;
@Column
private String content;
// Article 생성자 추가
public Article(Long id, String title, String content) {
this.id = id;
this.title = title;
this.content = content;
}
// toString() 메서드 추가
@Override
public String toString() {
return "Article{" +
"id=" + id +
", title='" + title + '\'' +
", content='" + content + '\'' +
'}';
}
}/entry/Article
package com.example.firstproject.controller;
import com.example.firstproject.dto.ArticleForm;
import com.example.firstproject.entity.Article;
import com.example.firstproject.repository.ArticleRepository;
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.PostMapping;
@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) {
System.out.println(form.toString()); // DTO에 폼 데이터가 잘 담겼는지 확인
// 1. DTO를 엔티티로 변환
Article article = form.toEntity();
System.out.println(article.toString()); // DTO가 엔티티로 잘 변환되는지 확인 출력
// 2. 리파지터리로 엔티티를 DB에 저장
Article saved = articleRepository.save(article);
System.out.println(saved.toString()); // article이 DB에 잘 저장되는지 확인 출력
return "";
}
}/ArticleController
4일차 : 게시판 만들기 : DB 데이터 조회
데이터베이스에 저장된 데이터를 조회하는 방법을 학습했습니다.

- DB 데이터 조회하기: 데이터베이스와 상호작용하며 쿼리문(SQL)을 통해 원하는 데이터를 가져오는 연습을 하였습니다.
- 롬복이란? getter, setter 등 반복적인 코드를 어노테이션을 통해 자동으로 생성해주는 라이브러리입니다. 롬복(Lookbok)은 개발 생산성을 크게 향상시키는 매우 유용한 도구인 것 같습니다.
- 목복을 활용한 리팩터링하기: 롬복을 적용하여 기존 코드를 더욱 간결하고 가독성 높게 개선했습니다. 코드가 깔끔해지면서 유지보수 측면에서도 이점이 많다는 것을 알 수 있었습니다.
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.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());
// System.out.println(form.toString()); // DTO에 폼 데이터가 잘 담겼는지 확인
// 1. DTO를 엔티티로 변환
Article article = form.toEntity();
log.info(article.toString());
// System.out.println(article.toString()); // DTO가 엔티티로 잘 변환되는지 확인 출력
// 2. 리파지터리로 엔티티를 DB에 저장
Article saved = articleRepository.save(article);
log.info(saved.toString());
// System.out.println(saved.toString()); // article이 DB에 잘 저장되는지 확인 출력
return "";
}
}5일차: 게시글 읽기(Read)
H2 DB를 이용하여 게시글 읽기(Read) 기능을 학습했습니다.
- 데이터 조회 과정: 데이터를 데이터베이스에서 가져와 화면에 표시하기까지의 전반적인 과정을 학습했습니다.
- 단일 데이터 조회: 특정 게시글 하나를 선택하여 상세 내용을 표시하는 방법을 학습했습니다.
- 데이터 목록 조회하기: 게시판에 존재하는 여러 게시글들을 목록 형태로 보여주는 방법을 익혔습니다. 이를 통해 기본적인 게시판 기능을 구현할 수 있게 되었습니다.
@GetMapping("/articles/{id}") // 데이터 조회 요청 접수
public String show(@PathVariable Long id, Model model) { // 매개변수로 id 받아 오기
log.info("id = " + id); // id를 잘 받았는지 확인하는 로그 찍기
// 1. id를 조회해 데이터 가져오기
// Optional<Article> articleEntity = articleRepository.findById(id);
Article articleEntity = articleRepository.findById(id).orElse(null);
// 2. 모델에 데이터 등록하기
model.addAttribute("article", articleEntity);
// 3. 뷰 페이지 반환하기
return "articles/show";
}
@GetMapping("/articles")
public String index(Model model) {
// 1. 모든 데이터 가져오기
List<Article> articleEntityList= articleRepository.findAll();
// List<Article> articleEntityList = (List<Article>)articleRepository.findAll();
// Iterable<Article> articleEntityList = articleRepository.findAll();
// 2. 모델에 데이터 등록하기
model.addAttribute("articleList", articleEntityList);
// 3. 뷰 페이지 설정하기
return "articles/index";
}1주차 마무리
이번 1주차 스프링 부트 학습을 통해서 스프링 부트의 기본 개념과 웹 서비스 동작 원리를 이해할 수 있었습니다.
MVC 패턴을 적용하여 뷰 템플릿 페이지를 구현하고, 게시판의 핵심 기능인 Create와 Read를 직접 만들어 보면서 웹 서비스의 기초를 다졌습니다. 특히 롬복 라이브러리를 활용하여 코드 작성 효율성을 크게 높일수 있었던 점이 인상 깊었습니다 .앞으로 남은 CRUD 기능 학습과 더 심화된 내용들을 통해 꾸준히 성장해 나가겠습니다.
