기본적으로 작업을 하기전에 application.yml에 jpa를 사용한다는 속성이 필요합니다.
jpa:
hibernate:
ddl-auto: create
properties:
hibernate: true
format_sql: true
show_sql:
dialect: org.hibernate.dialect.MySQL8Dialect
패키지 구조는
@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class FruitShop {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = 20)
private String name;
@Column
private Long price;
@Column
private int status;
@Column(name = "warehousing_date")
private LocalDate warehousingDate;
@Builder
private FruitShop(Long id, String name, Long price, int status, LocalDate warehousingDate) {
this.id = id;
this.name = name;
this.price = price;
this.status = status;
this.warehousingDate = warehousingDate;
}
}
리플렉션은 힙 영역에 로드된 Class 타입의 객체를 통해, 원하는 클래스의 인스턴스를 생성할 수 있도록 지원하고, 인스턴스의 필드와 메소드를 접근 제어자와 상관 없이 사용할 수 있도록 지원하는 API
public interface FruitShopJpaRepository extends JpaRepository<FruitShop, Long> {
}
/**
* JPA 서비스 클래스입니다.
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class FruitShopServiceV4 {
private final FruitShopJpaRepository fruitShopJpaRepository;
/**
* 제고를 입고하기 위한 서비스 로직입니다.
*/
public void warehousingFruit(FruitStockRequestDto request) {
//추후에 예외 처리를 넣을곳
saveValidation(request);
FruitShop fruitShop = FruitShop.builder()
.name(request.getName())
.status(0)
.price(request.getPrice())
.warehousingDate(request.getWarehousingDate()).build();
fruitShopJpaRepository.save(fruitShop);
log.info("과일 입고 성공!!");
}
/**
* 저장을 하기 위한 전 단계에 대한 예외 처리입니다.
*
* @param request
*/
private void saveValidation(FruitStockRequestDto request) {
if (request.getName() == null) {
throw new IllegalArgumentException("과일 이름이 존재하지 않습니다.");
}
if (request.getPrice() == null) {
throw new IllegalArgumentException("과일 이름이 가격이 존재하지 않습니다.");
}
}
/**
* 과일 판매를 위한 서비스 로직
*
* @param request 판매에 필요한 id값
*/
public void fruitSale(FruitSaleRequestDto request) {
FruitShop fruitShop = fruitShopJpaRepository.findById(request.getId()).orElseThrow(IllegalArgumentException::new);
FruitShop updateFruitShop = FruitShop.builder()
.name(fruitShop.getName())
.status(1)
.price(fruitShop.getPrice())
.warehousingDate(fruitShop.getWarehousingDate()).build();
fruitShopJpaRepository.save(updateFruitShop);
log.info("과일 판매 성공!!");
}
/**
* name값을 이용하여 계산된 과일과 계산이 되지않는 과일을 찾아내는 서비스 로직입니다.
*
* @param name
* @return
*/
public List<CalculatorSaleResponseDto> calculatorSale(String name) {
saleValidation(name);
return fruitShopJpaRepository.findSumSaleCalculator(name);
}
/**
* name값을 이용하여 계산된 과일과 계산이 되지않는 과일을 찾기전 유효성 검사로직입니다.
*
* @param name 검증받을 String값
*/
private void saleValidation(String name) {
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("name은 공백이 될수 없습니다.");
}
if (name.matches(".*" + "[!@#$%^&*()_+\\\\-=\\\\[\\\\]{};':\\"\\\\\\\\|,.<>\\\\/?]+" + ".*")) {
throw new IllegalArgumentException("이름에 특수문자 포함해 검색할 수 없습니다.");
}
}
public List<FruitListResponseDto> findAll() {
return fruitShopJpaRepository.findAll().stream()
.map((data) -> FruitListResponseDto.builder()
.id(data.getId())
.name(data.getName())
.price(data.getPrice())
.status(data.getStatus())
.warehousingDate(data.getWarehousingDate())
.build()).collect(Collectors.toList());
}
}