Spring에서는 데이터베이스와의 효율적인 통신을 위해 Spring JDBC와 Spring Data JPA를 제공합니다. 각각의 사용법과 관련 개념을 단계적으로 설명드리겠습니다.
Spring JDBC는 JDBC(Java Database Connectivity)를 더 편리하게 사용할 수 있도록 도와줍니다. JdbcTemplate은 Spring JDBC에서 제공하는 주요 클래스입니다.
spring-boot-starter-jdbc
를 의존성으로 추가하면 자동 설정됩니다.Maven 의존성:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
@Component
public class UserRepository {
private final JdbcTemplate jdbcTemplate;
public UserRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public List<User> findAll() {
String sql = "SELECT * FROM users";
return jdbcTemplate.query(sql, (rs, rowNum) ->
new User(rs.getLong("id"), rs.getString("name"), rs.getString("email"))
);
}
}
public void save(User user) {
String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
jdbcTemplate.update(sql, user.getName(), user.getEmail());
}
Spring Data JPA는 JPA(Java Persistence API)를 더 편리하게 사용할 수 있도록 도와주는 라이브러리입니다.
ORM(Object-Relational Mapping)을 기반으로 데이터베이스와 객체 간의 매핑을 처리합니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password:
jpa:
hibernate:
ddl-auto: update
show-sql: true
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// Getters, Setters, and Constructors
}
Spring Data JPA에서는 Repository 인터페이스를 통해 CRUD 작업을 쉽게 수행할 수 있습니다.
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
사용 예시:
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User saveUser(User user) {
return userRepository.save(user);
}
public List<User> findAllUsers() {
return userRepository.findAll();
}
}
Spring Data JPA는 메서드 이름으로 쿼리를 생성할 수 있는 기능을 제공합니다.
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByName(String name); // SELECT * FROM user WHERE name = ?
List<User> findByEmailContaining(String keyword); // LIKE '%keyword%'
}
JPQL은 엔티티 객체를 기반으로 쿼리를 작성하는 언어입니다.
@Query("SELECT u FROM User u WHERE u.email LIKE %:keyword%")
List<User> searchByEmail(@Param("keyword") String keyword);
Spring Data JPA는 페이징과 정렬을 간단하게 지원합니다.
public List<User> findAllUsers(Pageable pageable) {
return userRepository.findAll(pageable).getContent();
}
Pageable pageable = PageRequest.of(0, 10, Sort.by("name").ascending());
List<User> users = userRepository.findAll(pageable).getContent();
Spring은 데이터베이스 작업에서 트랜잭션을 효과적으로 관리할 수 있는 기능을 제공합니다.
주로 @Transactional
어노테이션을 통해 트랜잭션을 처리합니다.
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Transactional
public void saveUserAndEmail(User user) {
userRepository.save(user);
// 일부 작업 중 예외 발생 시 전체 롤백
if (user.getEmail() == null) {
throw new IllegalArgumentException("Email cannot be null");
}
}
}
트랜잭션이 실행되는 방식(전파 수준)을 설정할 수 있습니다.
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateUser(User user) {
userRepository.save(user);
}
추가 학습 자료
-[스프링 DB 1편 - 데이터 접근 핵심 원리] JDBC의 이해
-[Spring][DB] 스프링 DB 1편 - 데이터 접근 핵심 원리