Repository Interface 를 컨트롤러 클래스에서 직접 제어 하는것은 보안측면에서 좋지 않다. 또한 코드 중복을 막기 위해서도 서비스 클래스를 이용하여 DB 처리 하는것이 좋다. 서비스 클래스를 따로 두면 엔티티를 DTO 적용하여 데이터 처리를 분리 할 수 있다.
서비스는 비즈니스 로직을 담당한다.
- 컨트롤러 클래스 -> 서비스 클래스 함수 호출 -> 서비스 클래스에서 Repository Interface 조작
- @Service 어노테이션을 사용한다.
- Service 에는 @Transactional 메소드 어노테이션을 통해 DB 트랜잭션 작업을 하는 메소드를 작성 할 수 있다.
- @Transactional 어노테이션이 붙은 경우, 스프링 컨테이너는 Controller 에서 Service를 이용할때, 바로 주입하지 않고, Proxy 개체를 생성하여 활용한다.
- 따라서, Controller -> Proxy -> Service -> Repository 로 동작을 하게 되는 것이다.
서비스 예제
@Service
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
@Transactional
public Page<MemberDTO> searchMembersByName(String keyword, int page, int size) {
Pageable pageable = PageRequest.of(page, size, Sort.by("name").ascending());
Member member = memberRepository.findByNameContainingCustom(keyword, pageable);
MemberDTO dto = MemberDTO.fromEntity(member);
return dto;
}
}
컨트롤러 에서는 Repository 대신 서비스 클래스를 그대로 Injection 하여 사용하면 된다.
단, 리턴을 할때 엔티티를 직접 리턴하는것 보다 DTO로 변환하여 리턴하는것을 추천한다. 그 이유는 Lazy loading과 Transaction 연관이 있다. (여기 하단부에 해당 이유가 적혀 있다. https://dean83.tistory.com/343)
'Backend > SpringBoot' 카테고리의 다른 글
| DTO (W. Data, Build 어노테이션) (0) | 2024.10.24 |
|---|---|
| Paging (0) | 2024.10.24 |
| 응답으로 템플릿 리턴하기 (model, 타임리프, layout) (0) | 2024.10.23 |
| 의존성 주입 (List, Map 포함) (0) | 2024.10.23 |
| [기본구조3] Repository with JPA (DB CRUD동작,Interface, findby) (0) | 2024.10.23 |