백엔드

[Spring Boot] tave 스터디 1주차 개념 정리

밍들레밍 2026. 3. 22. 19:16

왜 spring boot를 써야하는가?

-> Spring Boot는 “웹 서비스나 서버 프로그램을 훨씬 쉽게 만들게 해주는 도구”라서, 자바만으로 서버를 만들면 너무 귀찮고 복잡하니까 Spring Boot를 쓰는 것!

스프링부트는

  • 서버를 쉽게 띄워줌
  • REST API 만들기 쉬움
  • DB 연결 쉽게 해줌
  • 객체를 JSON으로 바꿔줌
  • 설정 파일로 관리 가능
  • 에러 처리 구조도 잘 잡혀 있음

그래서 개발자가 “게시글 저장”, “회원가입”, “조회” 같은 진짜 기능 구현에 더 집중할 수 있다.

 

- API, 왜 필요한가요?

API (Application Programming Interface) : 웹 서비스에서 데이터를 주고받기 위한 규칙

 

HTTP (hypertext transfer protocol) : 웹 브라우저와 서버가 하이퍼텍스트, 즉 웹 페이지의 내용을 주고받을 때 사용하는 규칙

  • 비연결성(1회성 요청)
  • 무상태성
  • 클라이언트-서버 모델

 

- REST API

REST API (Reprsentational State Transfer) : 웹에서 데이터를 주고받기 위한 규칙

  • 자원은 URL(ex. http://localhost:8080/api/posts)로 표현
  • 행동은 HTTP메서드로 표현
  • 자원에는 명사 사용, 동사 사용 안함
  • 서버는 요청 결과에 따라 적절한 HTTP 상태코드 반환

구조 뜯어보기 (http://localhost:8080/api/posts)

  • Protocol: http (통신 규약)
  • Host (Domain): localhost (내 컴퓨터 주소)
  • Port: 8080 (스프링 부트가 열어둔 문 번호)
  • Path: /api/posts (서버 내부의 상세 경로 - 이게 바로 엔드포인트!)

Spring Boot에서 REST API를 많이 쓰는 이유는?

  1. HTTP랑 잘 맞음 : Spring Boot는 기본적으로 웹 서버 기반이고, REST는 HTTP 메서드를 그대로 잘 활용.
  2.  프론트엔드와 연결하기 쉬움 : React, Vue, Android, iOS 같은 클라이언트들은 보통 서버와 JSON 데이터로 통신함. REST API는 보통 JSON을 주고받으니까 프론트와 붙이기 편함.
  3. 서버와 클라이언트를 분리하기 좋음 : REST API는 화면을 서버가 직접 만들어 주는 방식이 아니라, 데이터만 제공하는 방식이라 역할 분리가 쉬움
  4. Spring Boot가 REST 개발을 매우 쉽게 지원함 : Spring Boot에서는 REST API를 거의 바로 만들 수 있다.
@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping("/{id}")
    public String getUser(@PathVariable Long id) {
        return "user " + id;
    }
}​
@RestController, @GetMapping 같은 어노테이션만 써도 빠르게 개발 가능해서 생산성이 높음

 

 

- Controller 실습

package com.example.springboot_twitter;

import com.example.springboot_twitter.repository.PostRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

@RequiredArgsConstructor //생성자 생성 역할
@RestController
public class PostController {

    private final PostRepository postRepository;


    @ResponseStatus(HttpStatus.CREATED)
    @PostMapping("/api/posts") //글쓰기
    public ResponseEntity<Post> createPost(@RequestBody Post post){
        Post newPost = new Post(null, post.getContent(), LocalDateTime.now());

        postRepository.save(newPost);

        return ResponseEntity
                .status(HttpStatus.CREATED)
                .body(newPost);
    }

    @GetMapping("/api/posts")
    public List<Post> getAllPosts(){
        return postRepository.findAll();
    }

    @GetMapping("/api/posts/{id}") //게시글 가져오기
    public Post getPost(@PathVariable Long id){
        return postRepository.findById(id).orElseThrow();
    }

    @PutMapping("/api/posts/{id}") //게시글 생성
    public Post updatePost(@PathVariable Long id, @RequestBody Post postRequest){
        return postRepository.findById(id).map(post->{
            post.updateContent(postRequest.getContent());
            return postRepository.save(post);
        }).orElseThrow();
    }

    @DeleteMapping("/api/posts/{id}") //게시글 삭제
    public void deletePost(@PathVariable Long id){
        postRepository.deleteById(id);
    }

    // /api/posts/search?page=1&size=3
    @GetMapping("/api/posts/search") //게시글 검색
    public List<Post> getAllPosts(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "3") int size
    ){
        return postRepository.findAllPaged(page,size);
    }
}

 

Controller : 클라이언트의 요청을 받아서 처리하는 역할을 하는 클래스, Spring Boot에서는 @Controller 또는 @RestController 어노테이션을 사용하여 컨트롤러를 만들 수 있다

 

--> 어노테이션 (annotation) 은 무엇인가?

자바에서 “이 클래스나 메서드는 이런 역할이에요”라고 표시해주는 표식

 

컨트롤러에서 자주 쓰는 어노테이션들

  • @Controller : 일반 컨트롤러
  • @RestController : 데이터 반환용 컨트롤러
  • @RequestMapping : 기본 URL 지정
  • @GetMapping : 조회
  • @PostMapping : 생성
  • @PutMapping : 전체 수정
  • @PatchMapping : 일부 수정
  • @DeleteMapping : 삭제
  • @PathVariable : URL 값 받기
  • @RequestParam : 쿼리스트링 값 받기
  • @RequestBody : 요청 본문의 JSON 받기

 

 

- Postman 으로 API 실습

Postman에 내가 만든 URL을 넣고, 거기에 맞는 HTTP 메서드(GET, POST 등) 를 설정해서 요청 보내면 됨!

나에게 가장 생소한 개념은 페이지네이션이었다.

 

페이지네이션 : 데이터를 한 번에 다 보여주지 않고, 여러 페이지로 나눠서 보여주는 것

.sorted((Post p1, Post p2) -> Long.compare(p2.getId(), p1.getId()))

p2를 앞에 두고 비교해서, id가 큰 값이 먼저 오게 만들었기 때문에 캡쳐본엔 0페이지에 큰 수부터 나오는 것. 

 

 

 

- Spring Data JPA 

JPA (Java Persistence API) : JPA는 자바 객체와 DB 테이블을 연결해서, SQL을 직접 다 많이 쓰지 않아도 DB 작업을 할 수 있게 해줌

 

Spring Data JPA  : Spring 애플리케이션에서 데이터베이스를 쉽게 사용할 수 있도록 도와주는 라이브러리. JPA를 기반으로 하며, 반복적인 데이터베이스 접근 코드를 줄이고 객체 지향적인 방식으로 데이터를 처리 할 수 있게 해.

예를 들어 원래는

  • EntityManager 써야 하고
  • persist, find 같은 걸 직접 다뤄야 하고
  • 조회 메서드도 구현해야 하는데

Spring Data JPA를 쓰면 인터페이스만 작성해도 기본 CRUD를 대부분 자동으로 제공

 

엔티티 (= DB 테이블과 연결되는 자바 클래스)

@Entity
public class Post {

@Id
@GeneratedValue
private Long id;

private String content;
}

 

Repository (= 엔티티를 DB에 저장하고 꺼내오는 역할 )

public interface PostRepository extends JpaRepository<Post, Long> {
}


postRepository.save(post);
postRepository.findAll();
postRepository.findById(1L);
postRepository.deleteById(1L);
바로 호출 가능

 

DTO (= 화면이나 API로 주고받기 위한 데이터 묶음)

public class PostResponseDto {
    private Long id;
    private String title;
}

DB 테이블에 직접 연결되는 게 아닌,  응답용 / 요청용 데이터 상자

 

정리

 

  1. Spring Data JPA는 DB 작업을 쉽게 해준다
  2. 그런데 뭘 대상으로 쉽게 하냐?
  3. 바로 엔티티
  4. 그 엔티티를 다루는 통로가 Repository

 

 

 

- 인메모리 저장소 H2 Database 연결하기

PostRepository

package com.example.springboot_twitter.repository;

import com.example.springboot_twitter.Post;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

public interface PostRepository {

    Post save(Post post);
    List<Post> findAll();
    Optional<Post> findById(Long id);
    void deleteById(Long id);
    List<Post> findAllPaged(int page, int size);
}

InMemoryPostRepository

package com.example.springboot_twitter.repository;

import com.example.springboot_twitter.Post;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Repository;

import java.util.*;
import java.util.concurrent.atomic.AtomicLong;

@Repository
public class InMemoryPostRepository implements PostRepository
{
    private final Map<Long,Post> posts = new HashMap<>(); //실제 DB 대신하는 임시저장소
    private final AtomicLong idGenerator = new AtomicLong(1);//자동 번호표기계


    @Override
    public Post save(Post post) {
        Long id = post.getId() == null ? idGenerator.getAndIncrement() : post.getId();
        post.setId(id);
        posts.put(id,post);
        return post;
    }

    @Override
    public List<Post> findAll() {
        return new ArrayList<>(posts.values());
    }

    @Override
    public Optional<Post> findById(Long id) {
        return Optional.ofNullable(posts.get(id));
    }

    @Override
    public void deleteById(Long id) {
        posts.remove(id);
    }

    @Override
    public List<Post> findAllPaged(int page, int size) {
        return posts.values()
                .stream()
                .sorted((Post p1, Post p2)->Long.compare(p2.getId(), p1.getId()))
                .skip((long) page*size)
                .limit(size)
                .toList();
    }
}

 

 

 

- MySql database 설정하기

 

Spring Boot 프로젝트 설정하기

build.gradle 파일에 MySQL 의존성을 추가

dependencies {
  // MySQL 드라이버
  implementation("com.mysql:mysql-connector-j")

 

데이터베이스 연결 설정

application.properties 파일에 MySQL 연결 정보를 설정

spring:
  datasource:
  url: jdbc:mysql://localhost:3306/twitterdb
  username: dev
  password: dev123 

 

db연결완룡