스프링 with AI

Gemini와 함께하는 Spring 08

ohji52 2025. 9. 8. 10:16

스프링 공부한 것을 Todolist 예시로 만들기

스프링 3계층 아키텍쳐

 

1. 모델(Model)

역할:  애플리케이션의 데이터를 담는 그릇(데이터 객체)

 

코드:

package com.example.todolistpractice.domain;

public class Todo {
    private Long id; // 아이디
    private String content; // 내가 입력한 할 일
    private boolean completed; // 할 일의 완료 여부

    // 기본 생성자 (필수)
    public Todo() {
    }

    public Todo(String content, boolean completed) {
        this.content = content;
        this.completed = completed;
    }


    //getter and setter
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public boolean isCompleted() {
        return completed;
    }

    public void setCompleted(boolean completed) {
        this.completed = completed;
    }
}

2. 리포지토리(Repository)

역할:  데이터 저장소(DB, 파일 등)와 상호작용

 

코드:

package com.example.todolistpractice.repository;

import com.example.todolistpractice.domain.Todo;
import org.springframework.stereotype.Repository;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional; // 값이 존재할수도 안할수도 있는 객체를 안전하게 다루기 위한 자바의 컨테이너(wrapper) 클래스
import java.util.concurrent.atomic.AtomicLong; //atomic은 원자적 연산을 보장
import java.util.stream.Collectors;

@Repository
public class TodoRepository {
    private static final Map<Long, Todo> store = new HashMap<>(); // 할 일 저장
    private static final AtomicLong sequence = new AtomicLong(0L);

    public Todo save(Todo todo) {
        if (todo.getId() == null) {
            todo.setId(sequence.incrementAndGet()); //sequence 값을 원자적으로 1증가시켜서 id 값 설정
        }
        store.put(todo.getId(), todo);
        return todo;
    }

    public Optional<Todo> findById(Long id) {
        return Optional.ofNullable(store.get(id)); //반환값이 null 일 수 있으므로 사용되는 optional.ofnullable
    }

    public List<Todo> findAll() {
        return store.values().stream().collect(Collectors.toList()); // 스토어에 있는 값들을 리스트 형태로 변화 후 반환
    }

    public void deleteById(Long id) {
        store.remove(id);
    }

    public void update(Long id, Todo updateParam) {
        Todo findTodo = store.get(id);
        if (findTodo != null) {
            findTodo.setContent(updateParam.getContent());
            findTodo.setCompleted(updateParam.isCompleted());
        }
    }
}

3. 서비스(Service)

역할:  핵심 비즈니스 로직 처리, 컨트롤러와 리포지토리 사이에서의 로직 수행

 

코드:

package com.example.todolistpractice.service;

import com.example.todolistpractice.domain.Todo;
import com.example.todolistpractice.repository.TodoRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
public class TodoService {

    private final TodoRepository todoRepository;

    @Autowired
    public TodoService(TodoRepository todoRepository) {
        this.todoRepository = todoRepository;
    }

    public Long createTodo(Todo todo) { // todo생성
        todoRepository.save(todo);
        return todo.getId();
    }

    public List<Todo> findAllTodos() { // 모든 todo 찾기
        return todoRepository.findAll();
    }

    public Optional<Todo> findById(Long id) { // 아이디를 통해 찾기
        return todoRepository.findById(id);
    }

    public void deleteTodo(Long id) { // 삭제
        todoRepository.deleteById(id);
    }

    public void updateTodo(Long id, Todo todo) { // 수정
        todoRepository.update(id, todo);
    }
}

4. 컨트롤러(Controller)

역할:  웹 요청을 받고 응답 반환

 

코드:

package com.example.todolistpractice.controller;

import com.example.todolistpractice.domain.Todo;
import com.example.todolistpractice.service.TodoService;
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("/")
public class TodoController {

    private final TodoService todoService;

    @Autowired
    public TodoController(TodoService todoService) {
        this.todoService = todoService;
    }

    @GetMapping
    public String list(Model model) {  // 리스트 전체 검색
        List<Todo> todos = todoService.findAllTodos();
        model.addAttribute("todos", todos);
        return "index";
    }

    @PostMapping("/add")
    public String addTodo(@ModelAttribute Todo todo) {  // 추가
        todoService.createTodo(todo);
        return "redirect:/";
    }

    @PostMapping("/delete/{id}")
    public String deleteTodo(@PathVariable Long id) { // 삭제
        todoService.deleteTodo(id);
        return "redirect:/";
    }

    @PostMapping("/update/{id}")
    public String updateTodo(@PathVariable Long id, @ModelAttribute Todo todo) { //수정
        todoService.updateTodo(id, todo);
        return "redirect:/";
    }
}

'스프링 with AI' 카테고리의 다른 글

Gemini와 함께하는 Spring 10  (0) 2025.09.14
Gemini와 함께하는 Spring 09  (0) 2025.09.09
Gemini와 함께하는 Spring 07  (0) 2025.09.02
GPT와 함께하는 Spring 06  (1) 2025.09.01
GPT와 함께하는 Spring 05  (0) 2025.09.01