스프링 부트(Spring Boot)는 현대 웹 애플리케이션을 쉽게 개발할 수 있게 해주는 프레임워크로, 특히 백엔드 개발에 널리 사용됩니다. 이번 강좌에서는 스프링 부트와 데이터베이스의 관계, 데이터베이스와의 통신 방법, 엔티티, 리포지토리, 트랜잭션 관리 등 다양한 측면을 탐구하겠습니다.
1. 스프링 부트와 데이터베이스
스프링 부트는 Java 기반의 프레임워크로, 데이터베이스와의 통신을 효율적으로 처리할 수 있는 여러 가지 기능을 제공합니다. 관계형 데이터베이스(RDBMS)와 비관계형 데이터베이스(NoSQL) 모두를 지원하며, 데이터베이스 연동에 필요한 복잡한 설정을 최소화할 수 있습니다.
1.1 데이터베이스 연결
스프링 부트에서는 데이터베이스 연결을 설정하기 위해 application.properties 또는 application.yml 파일을 사용합니다. 데이터베이스의 URL, 사용자 이름, 비밀번호 등을 설정할 수 있습니다.
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=myuser
spring.datasource.password=mypassword
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
1.2 JPA와 Hibernate
스프링 부트는 JPA(Java Persistence API)를 지원하며, Hibernate를 기본 JPA 구현체로 사용합니다. JPA는 자바 객체와 데이터베이스 간의 매핑을 위한 API로, SQL 쿼리를 작성하지 않고도 데이터베이스 작업을 수행할 수 있게 도와줍니다.
2. 데이터베이스 모델링
애플리케이션의 데이터베이스 구조를 설계하는 것은 매우 중요합니다. 데이터베이스 모델링에는 다음과 같은 과정이 포함됩니다.
2.1 엔티티와 관계 설정
각 테이블을 엔티티 클래스로 모델링합니다. 예를 들어, 사용자와 주문 엔티티가 있다고 가정해보겠습니다.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// Getters and Setters
}
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
private String product;
private Double price;
// Getters and Setters
}
2.2 데이터베이스 마이그레이션
스프링 부트에서는 데이터베이스 스키마의 변경을 자동으로 관리하기 위해 Flyway 또는 Liquibase와 같은 마이그레이션 도구를 사용할 수 있습니다. 이를 통해 데이터베이스 변경 사항을 버전 관리할 수 있습니다.
3. CRUD 연산 구현
데이터베이스와의 상호작용에서 가장 기본적인 작업은 CRUD(Create, Read, Update, Delete)입니다. 이를 구현하기 위해 리포지토리 패턴을 사용합니다.
3.1 사용자 리포지토리
public interface UserRepository extends JpaRepository {
List findByName(String name);
}
3.2 서비스 레이어
비즈니스 로직을 처리하는 서비스 클래스를 작성합니다.
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public User createUser(User user) {
return userRepository.save(user);
}
public List getAllUsers() {
return userRepository.findAll();
}
// Update and Delete methods
}
3.3 컨트롤러
HTTP 요청을 처리하는 REST 컨트롤러를 구현합니다.
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public ResponseEntity createUser(@RequestBody User user) {
return ResponseEntity.ok(userService.createUser(user));
}
@GetMapping
public List getAllUsers() {
return userService.getAllUsers();
}
// Update and Delete endpoints
}
4. 트랜잭션 관리
스프링 부트에서는 @Transactional 어노테이션을 사용하여 트랜잭션 관리를 쉽게 할 수 있습니다. 트랜잭션이란 데이터베이스에 대한 일련의 작업이 모두 성공적으로 수행되거나 모두 실패해야 하는 작업의 단위입니다.
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private UserRepository userRepository;
@Transactional
public void createOrder(Order order, Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("User not found"));
order.setUser(user);
orderRepository.save(order);
}
}
5. 데이터베이스와의 에러 처리
데이터베이스와의 통신에서 발생할 수 있는 다양한 에러를 처리하는 것은 매우 중요합니다. 예를 들어, 데이터베이스가 다운되었거나 쿼리에 오류가 발생했을 때 적절한 예외 처리가 필요합니다.
5.1 커스텀 예외 클래스
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
5.2 글로벌 예외 처리
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity handleNotFound(ResourceNotFoundException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
}
}
6. 테스트와 배포
마지막으로, 개발한 애플리케이션을 안전하게 배포하기 위해서는 테스트가 필수적입니다. 스프링 부트에서는 JUnit 및 Mockito를 활용하여 단위 테스트 및 통합 테스트를 수행할 수 있습니다.
6.1 단위 테스트
@SpringBootTest
public class UserServiceTests {
@Autowired
private UserService userService;
@MockBean
private UserRepository userRepository;
@Test
public void testCreateUser() {
User user = new User();
user.setName("Test User");
user.setEmail("test@example.com");
Mockito.when(userRepository.save(user)).thenReturn(user);
User createdUser = userService.createUser(user);
assertEquals("Test User", createdUser.getName());
}
}
6.2 배포하기
스프링 부트 프로젝트는 jar 파일로 패키징되어 AWS, Azure, Google Cloud와 같은 클라우드 환경에 쉽게 배포할 수 있습니다.
결론
이번 강좌를 통해 스프링 부트를 이용한 백엔드 개발과 데이터베이스 연결에 대한 포괄적인 내용을 다루었습니다. CRUD 작업 구현, 트랜잭션 관리, 에러 처리, 테스트 및 배포에 이르기까지 스프링 부트를 활용한 데이터베이스 통합의 기본 개념을 이해하셨길 바랍니다. 이 내용을 바탕으로 여러분의 프로젝트에 스프링 부트를 적용해 보세요!