최종 정리 (한 줄 요약!)
1. CrudRepository<T, ID> 제너릭 인터페이스 제공
2. UserRepository extends CrudRepository<User, Long> 형태로 실 매개 타입 전달
3. Spring이 UserRepository의 구현체를 자동 생성
4. 개발자는 UserRepository를 상속받은 인터페이스만 정의하면 CRUD 기능 사용 가능
5. Spring Data JPA가 인터페이스를 기반으로 자동으로 CRUD 쿼리를 실행
결론: "인터페이스만 만들면 Spring이 알아서 CRUD를 다 해준다"
Spring Data JPA의 CRUD 자동 처리 과정
[CrudRepository 제너릭 인터페이스]
Spring Data JPA는 CrudRepository<T, ID>라는 제너릭 인터페이스를 제공함.
- 여기서 T는 엔티티 타입, ID는 기본 키 타입을 의미함.
- CrudRepository를 상속받으면 기본적인 CRUD 메서드를 자동으로 제공함.
public interface CrudRepository<T, ID> {
<S extends T> S save(S entity); // 저장 및 수정
Optional<T> findById(ID id); // 조회
boolean existsById(ID id); // 존재 여부 확인
Iterable<T> findAll(); // 전체 조회
void deleteById(ID id); // 삭제
}
[실 매개 타입 전달]
개발자가 직접 "엔티티 클래스"와 "기본 키 타입"을 지정하면서 "CrudRepository를 확장한 인터페이스"를 정의함.
- 예를 들어, User 엔티티의 기본 키 타입이 Long이면 다음과 같이 정의함.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
public interface UserRepository extends CrudRepository<User, Long> {
}
여기서 CrudRepository<User, Long>의 제너릭 타입에 실제 엔티티(User)와 기본 키 타입(Long)을 전달함.
[인터페이스를 구현]
Spring Data JPA는 UserRepository 인터페이스를 직접 구현하지 않아도 자동으로 구현 클래스를 생성함.
즉, 개발자가 UserRepository에 @Repository를 붙이거나 직접 구현할 필요 없음.
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void saveUser(User user) {
userRepository.save(user);
}
}
이때, userRepository.save(user)를 호출하면 자동으로 INSERT 또는 UPDATE 쿼리를 실행함.
[속받는 리포지터리 인터페이스를 정의하면]
개발자가 CrudRepository 또는 JpaRepository를 확장하는 인터페이스를 정의하기만 하면, Spring Data JPA가 이를 자동으로 감지하고 CRUD 기능을 제공함.
JpaRepository는 CrudRepository를 확장한 인터페이스로, 더 많은 기능을 제공함.
(예: findAll(Pageable pageable), flush(), saveAndFlush() 등)
public interface UserRepository extends JpaRepository<User, Long> {
}
[DATA JPA는 이 인터페이스를 사용하여 자동으로 CRUD 기능을 구현함]
Spring Data JPA는 인터페이스 기반 프록시 객체를 생성하여 내부적으로 JDBC 또는 Hibernate를 통해 CRUD 작업을 수행함.
즉, @Autowired로 UserRepository를 주입받으면, Spring이 자동으로 구현체를 생성하여 사용할 수 있음.
@RestController
@RequestMapping("/users")
public class UserController {
private final UserRepository userRepository;
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
return userRepository.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
public User createUser(@RequestBody User user) {
return userRepository.save(user);
}
}
위처럼 userRepository.findById(id), userRepository.save(user)를 호출하면,
Spring Data JPA가 자동으로 SQL 쿼리를 생성하여 실행함.
'IT개발 > Spring Boot3' 카테고리의 다른 글
[Spring Boot3] Logger & SLF4J 구현체 (0) | 2025.04.20 |
---|---|
[Spring Boot3]JPA의 기본 어노테이션 (0) | 2025.04.06 |
[Spring Boot3] 의존성 주입(Dependency Injection) 이해하기(이걸로 끝) (0) | 2025.03.20 |
[Spring Boot3] JSP를 사용하지 않는 이유 & JPA, JSON 개념(간단) (0) | 2025.03.20 |
[Spring Boot] 개발 환경 설정부터 H2 데이터베이스 웹 연결 (0) | 2024.11.28 |