
Spring Boot 애플리케이션에서는 MVC(Model-View-Controller) 패턴을 사용하여 애플리케이션을 구조화할 수 있으며, Controller, Service, DAO, Mapper는 애플리케이션을 모듈화하고 유지 보수하기 쉽게 만드는 데 중요한 역할을 한다.
1. Controller
클라이언트 요청을 처리하고, 요청에 따라 적절한 서비스를 호출하여 결과를 반환한다. 주로 HTTP 요청을 매핑하고, 요청 데이터를 바인딩하며, 서비스 계층을 호출한다.
package com.example.demo.controller;
import com.example.demo.dto.UserDTO;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController // RESTful 웹 서비스의 컨트롤러임을 나타냄
@RequestMapping("/api/users") // 컨트롤러가 처리할 기본 URL 경로를 지정
public class UserController {
private final UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping // HTTP GET 요청을 이 메서드에 매핑합니다.
public ResponseEntity<List<UserDTO>> getAllUsers() {
List<UserDTO> users = userService.getAllUsers();
return ResponseEntity.ok(users);
}
@GetMapping("/{id}") // 경로 변수 id를 포함한 HTTP GET 요청을 매핑
public ResponseEntity<UserDTO> getUserById(@PathVariable Long id) {
UserDTO user = userService.getUserById(id);
return ResponseEntity.ok(user);
}
@PostMapping // HTTP POST 요청을 매핑
public ResponseEntity<UserDTO> createUser(@RequestBody UserDTO userDTO) {
UserDTO createdUser = userService.createUser(userDTO);
return ResponseEntity.status(201).body(createdUser);
}
@PutMapping("/{id}") // 경로 변수 id를 포함한 HTTP PUT 요청을 매핑
public ResponseEntity<UserDTO> updateUser(@PathVariable Long id, @RequestBody UserDTO userDTO) {
UserDTO updatedUser = userService.updateUser(id, userDTO);
return ResponseEntity.ok(updatedUser);
}
@DeleteMapping("/{id}") // 경로 변수 id를 포함한 HTTP DELETE 요청을 매핑
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
return ResponseEntity.noContent().build();
}
}
2. Service
비즈니스 로직을 처리. Service 계층은 Controller와 DAO 간의 중간 계층으로, 비즈니스 요구사항을 구현하고 트랜잭션을 관리한다.
package com.example.demo.service;
import com.example.demo.dto.UserDTO;
import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service // 이 클래스가 서비스 계층의 빈임을 나타냄
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public List<UserDTO> getAllUsers() {
// 모든 사용자를 조회하고 DTO 목록으로 변환
return userRepository.findAll().stream()
.map(this::convertToDTO)
.collect(Collectors.toList());
}
public UserDTO getUserById(Long id) {
// ID로 사용자를 조회하고, 없으면 예외를 발생
User user = userRepository.findById(id).orElseThrow(() -> new RuntimeException("User not found"));
return convertToDTO(user);
}
public UserDTO createUser(UserDTO userDTO) {
// DTO를 엔티티로 변환하고 저장한 후, 다시 DTO로 변환
User user = convertToEntity(userDTO);
User savedUser = userRepository.save(user);
return convertToDTO(savedUser);
}
public UserDTO updateUser(Long id, UserDTO userDTO) {
// ID로 기존 사용자를 조회하고 업데이트한 후 저장
User existingUser = userRepository.findById(id).orElseThrow(() -> new RuntimeException("User not found"));
existingUser.setName(userDTO.getName());
existingUser.setEmail(userDTO.getEmail());
User updatedUser = userRepository.save(existingUser);
return convertToDTO(updatedUser);
}
public void deleteUser(Long id) {
// ID로 사용자를 삭제
userRepository.deleteById(id);
}
private UserDTO convertToDTO(User user) {
// 엔티티를 DTO로 변환
return new UserDTO(user.getId(), user.getName(), user.getEmail());
}
private User convertToEntity(UserDTO userDTO) {
// DTO를 엔티티로 변환
return new User(userDTO.getId(), userDTO.getName(), userDTO.getEmail());
}
}
3. Mapper
주로 MyBatis와 같은 ORM 도구를 사용할 때 데이터베이스와의 매핑을 담당.
Read-Only Mapper
package com.example.demo.mapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper // 이 인터페이스가 MyBatis 매퍼 인터페이스임을 나타냄
public interface UserReadOnlyMapper {
@Select("SELECT * FROM users WHERE id = #{id}")
User findById(Long id);
@Select("SELECT * FROM users")
List<User> findAll();
}
Read-Write Mapper
package com.example.demo.mapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.*;
@Mapper // 이 인터페이스가 MyBatis 매퍼 인터페이스임을 나타냄
public interface UserReadWriteMapper {
@Insert("INSERT INTO users(name, email) VALUES(#{name}, #{email})")
@Options(useGeneratedKeys = true, keyProperty = "id")
void insert(User user);
@Update("UPDATE users SET name = #{name}, email = #{email} WHERE id = #{id}")
void update(User user);
@Delete("DELETE FROM users WHERE id = #{id}")
void deleteById(Long id);
}
4. DTO (Data Transfer Object)
계층 간 데이터 전송을 위한 객체
package com.example.demo.dto;
@Getter
@Setter
public class UserDTO {
private Long id;
private String name;
private String email;
public UserDTO() {
}
public UserDTO(Long id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
}
'Spring Boot' 카테고리의 다른 글
[Spring Boot] 암호화/복호화(AES, RSA, BCrypt) (2) | 2024.07.24 |
---|---|
[Spring Boot] 어노테이션(Annotation) (0) | 2024.07.24 |
[Spring Boot] 필터(Filter) (2) | 2024.07.24 |
[Spring Boot] 트랜잭션(Transaction) (0) | 2024.07.19 |
[Spring Boot] Batch 기본 개념 (0) | 2024.07.18 |