JPA Entity to Dto, Pageable 사용 예
내가 자바 스프링을 제대로 배운적이 있는건 아니다. 어쩌다보니 흉내나 내게 생겼는데 년초부터 조금씩 하면서 궁금해하던 부분들이 요즘 다시 부각되고 있어 이참에 제대로 함 이해하고 넘어가자고 파고 들었는데 ... 정작 이해하기는 어렵다.
공부를 해야할 시간이 절대적으로 필요하다. 게을러 잘 안되는것도 문제다.
JPA를 이용하는 것은 편리한 부분이 분명 존재한다. 다만 원리와 구조를 이해하기보다는 대체적으로 사용하는 예시를 보고 따라하는 식이다 보니 마음대로 구현하기가 쉽지 않다.
보통 스프링 개발을 할 때 Entity(table) 와 DTO를 만들어 사용하게 되고 보통 Repository를 통해 Entity를 리턴 받아 DTO로 변환해서 사용하게 된다.
나의 경우는 그냥 Entity를 모델로 내려주고 타임리프에서 가공해서 사용하곤 했는데 까딱 잘못하다간 데이터베이스의 데이터가 조작되기 십상이다. 그래서 이번 프로젝트에서는 번거롭더라도 꼭 DTO를 만들어서 사용하려고 한다.
먼저 Entity를 생성했다.
@Entity
@Getter
@Setter
@ToString
@Table(name = "")
public class BankIntegratedManager {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "code")
private Long seq;
/**
* 금융사코드
*/
@Column(name = "bank_code")
private String bankCode;
그런 다음 DTO를 만들었다.
@Getter
@Setter
public class BankIntegratedManagerDTO implements Serializable {
private Long seq;
/**
* 금융사코드
*/
private String bankCode;
그리고 Service I/F를 정의했다.
public interface IAccountService {
/**
* 전체 리스트
* @param pageable
* @return
*/
Page<BankIntegratedManagerDTO> findAll(Pageable pageable);
}
여기서 보통 Page<BankIntegratedManager> 이런식으로 JpaRepository를 호출하는데 Service에서는 예제처럼 DTO로 받기 위해서 타입을 변경했다.
Service Implements는 다음과 같이 구현했다.
@Service
public class AccountServiceImpl implements IAccountService {
@Autowired
BankIntegratedManagerRepository bankIntegratedManagerRepository;
@Autowired
BankIntegratedManagerMapper bankIntegratedManagerMapper;
/**
* 전체 리스트
* @param pageable
* @return
*/
@Override
public Page<BankIntegratedManagerDTO> findAll(Pageable pageable) {
pageable = PageRequest.of(pageable.getPageNumber() <= 0 ? 0 : pageable.getPageNumber()-1, pageable.getPageSize(), new Sort(Sort.Direction.DESC, "seq"));
Page<BankIntegratedManager> managers = bankIntegratedManagerRepository.findAll(pageable);
return new PageImpl<>(bankIntegratedManagerMapper.toDto(managers.getContent()), pageable, managers.getTotalElements());
}
}
Page<BankIntegratedManager>로 받아 PageImple를 이용해서 DTO로 변환을 해서 Page<BankIntegratedManagerDTO>로 리턴이 되도록 했다.
이를 받는 Controller는 다음과 같다.
/**
* 계정 리스트
*/
@GetMapping("/account")
public String list(@PageableDefault Pageable pageable, Model model) {
Page<BankIntegratedManagerDTO> managers = accountService.findAll(pageable);
model.addAttribute("managers", managers);
return "/account";
}
지금까지는 Mapper를 사용한 적이 없고 하기 귀찮아서 entityToDto() 같은 메서드로 수동 매핑을 했다. 왜냐고?
그냥 내 스타일?
이번엔 Mapper를 활용했고 Mapper는 다음과 같다.
public interface EntityMapper <D, E> {
E toEntity(D dto);
D toDto(E entity);
List <E> toEntity(List<D> dtoList);
List <D> toDto(List<E> entityList);
}
EntityMapper<D, E>를 상속 받는 interface를 정의했다.
@Component
@Mapper(componentModel = "spring", uses = {})
public interface BankIntegratedManagerMapper extends EntityMapper<BankIntegratedManagerDTO, BankIntegratedManager>{
default BankIntegratedManager fromId(Long id) {
if (id == null) {
return null;
}
BankIntegratedManager manager = new BankIntegratedManager();
manager.setSeq(manager.getSeq());
return manager;
}
}
마치 수학공식같이 정해진 패턴대로 착착 정의하고 구현해주고 하면 신기하게도 리스트가 만들어진다. ㅋㅋㅋ
참 좋은 세상.
몇일전 구입한 스프링부트 책 두 권을 정독하면서 따라 해보고 정리를 해바야겠다.
차근차근 하나씩 하나씩 !!
'프로그래밍 > Spring' 카테고리의 다른 글
스프링 DevTools사용 설정 (0) | 2019.12.13 |
---|---|
스프링부트 프로젝트 Java 애플리케이션으로 실행하는 방법 (0) | 2019.12.13 |
BCrypt알고리즘 해시로 만든 암호 (0) | 2019.04.25 |
@AuthenticationPrincipal userDetail를 사용하는 예제 (0) | 2019.04.25 |
WebSecurity configure (0) | 2019.04.25 |